ScriptableObject는 스크립트 인스턴스에서 독립적인 대량의 공유 데이터를 저장할 수 있게 하는 클래스입니다. 이름이 비슷한 에디터 클래스 SerializableObject는 목적이 다르므로 혼동해서는 안됩니다. 정수 백만 개의 배열을 가진 스크립트로 프리팹을 작성한 경우를 예로 들어보겠습니다. 배열의 메모리는 4MB이며 프리팹에 있습니다. 해당 프리팹을 인스턴스화할 때마다 이 배열이 복제됩니다. 게임 오브젝트 10개를 생성하면 10개 인스턴스에 40MB의 데이터 배열이 생기는 것입니다.
Unity는 Vector3와 같이 프리미티브 타입, 스트링, 배열, 리스트, Unity에 특화된 타입뿐만 아니라 복사 처럼 선언된 오브젝트에 속한 Serializable 속성을 가진 커스텀 클래스 모두를 시리얼라이즈 합니다. 이는 사용자가 ScriptableObject를 생성하고 백만 개의 정수를 배열에 저장하면 배열이 해당 인스턴스와 함께 저장됨을 뜻합니다. 인스턴스는 개별 데이터를 보유하는 것으로 판단됩니다. ScriptableObject 필드나 MonoBehaviour, Mesh, GameObject와 같은 모든 UnityEngine.Object 필드는 값이 아니라 _ 레퍼런스_로 저장됩니다. 백만 개의 정수가 있는 ScriptableObject를 참조하는 스크립트가 있다면 Unity는 스크립트 데이터에 ScriptableObject에 대한 레퍼런스만 저장합니다. 그리고 ScriptableObject는 배열을 저장합니다. ScriptableObject에 대한 레퍼런스를 갖는 4MB의 프리팹 인스턴스 10개는 그 데이터 총합이 다른 예처럼 40MB가 아니라 약 4MB입니다.
ScriptableObject는 값의 복제를 피해 메모리 소비를 줄이려는 경우에 사용하지만, 장착형 데이터 집합을 정의할 때도 활용할 수 있습니다. RPG 게임의 NPC 샵이 그 예입니다. 사용자 지정 ShopContents ScriptableObject에서 여러 에셋을 생성하고 각각 구매 가능한 항목을 정의할 수 있습니다. 게임에 존이 세 곳 있는 경우 각 존은 서로 다른 등급의 아이템을 제공할 수 있습니다. 샵의 스크립트는 어떤 항목이 가능할지 정의하는 ShopContents 오브젝트를 참조합니다. 예시는 스크립팅 레퍼런스를 참조하십시오.
ScriptableObject 파생 클래스를 정의하고 나면 클래스를 사용해 커스텀 에셋을 손쉽게 생성하도록 CreateAssetMenu 속성을 사용할 수 있습니다.
팁: 인스펙터에서 ScriptableObject 레퍼런스로 작업할 때 레퍼런스 필드를 더블 클릭해서 ScriptableObject의 인스펙터를 열 수 있습니다. 또한 인스펙터가 나타내는 데이터의 관리에 도움이 되도록 모양을 정의해 커스텀 에디터를 만들 수도 있습니다.