오늘 게임 개발을 진행하다가 Scriptable Object라는 것을 알게 되었다.
Scriptable Object가 무엇이냐?
Unity 공식 문서에 따르면 Scriptable Object는 클래스 인스턴스와는 별도로 대량의 데이터를 저장하는 데 사용할 수 있는 데이터 컨테이너이다.


Scriptable Object의 주요 사용 사례 중 하나는 값의 사본이 생성되는 것을 방지하여 프로젝트의 메모리 사용을 줄이는 것이다.
이게 무슨 소리냐면 일반적으로 Prefab을 만들어서 인스턴스화 시키면 해당 Prefab이 가지고 있는 값의 사본이 메모리에 적재된다.
하나의 Prefab으로 100개의 인스턴스를 시키면 똑같은 값들이 메모리에 100개 올라가있다는 소리이다.
생각만해도 비효율적인데 여기서 사용하는 것이 Scriptable Object이다.
예를 들어, Human이라는 Prefab를 만들기 위해 Human에 필요한 정보(체력, 이동속도, 데미지, 공격속도 등)를 저장하는 A라는 Scriptable Object를 만들었다고 가정하자.
A에 필요한 정보들을 모두 저장한 후 Human Prefab이 A를 가진채로 인스턴스화되면 메모리에 A에 저장되어있는 값들의 사본이 생기는 것이 아닌 A 자체를 참조하게 된다.
즉, Human Prefab으로 몇 개를 인스턴스화 하던 모든 Human Object는 각자만의 데이터를 가지는 것이 아닌 A 하나를 공유하고 있다.
그렇다면 이 Scriptable Object를 어떻게 만드는지를 알아보겠다.
Scriptable Object를 만들려면 ScriptableObject를 상속받아야한다.

이후 Human에 필요한 값들을 모두 선언하고나서 Class 코드 상단에
[CreateAssetMenu(fileName = "DataName", menuName = "File Path")]를 적어주면 된다.
나는 아래와 같이 간단하게 만들었다.
[CreateAssetMenu(fileName = "Human", menuName = "Scriptable Object/HumanData")]
public class Human : ScriptableObject
{
[SerializeField] private int hp;
public int Hp => hp;
[SerializeField] private float moveSpeed;
public float MoveSpeed => moveSpeed;
[SerializeField] private float damage;
public float Damage => damage;
}
이렇게 Script를 만들고나면 Project Tab에서 Scriptable Object를 만들 수 있다.

ItemData는 내가 따로 만들어놨던 Scriptable Object이다.
생성하면 Human Data를 설정할 수 있는 Object가 만들어진다.


Inspector에서 값을 설정한 후 Human Prefab이 Scriptable Object를 갖고있게 하면 된다.
그런 후 Human Prefab을 인스턴스화하면 위 값을 가지는 Object가 되는 것이다.
몇 개를 인스턴스화해도 모든 Human Object는 위 Scriptable Object 하나를 공유하며 모두 Hp=5, MoveSpeed=3, Damage=2를 갖는다.
또한 Data를 수정할 경우 모든 Human Object에 즉시 반영된다.
만약 Human Object마다 값이 달라야한다면 Scriptable Object를 사용할 수 없지만, 같은 값을 가지는 Object를 여러 개 생성해야한다면 Scriptable Object는 좋은 선택지가 될 수 있을 것이다.