스트리밍 에셋
고급 에디터 토픽

ScriptableObject

ScriptableObject란?

ScriptableObject는 클래스 인스턴스와는 별도로 대량의 데이터를 저장하는 데 사용할 수 있는 데이터 컨테이너입니다. ScriptableObject의 주요 사용 사례는 값의 사본이 생성되는 것을 방지하여 프로젝트의 메모리 사용을 줄이는 것입니다. 이는 첨부된 MonoBehaviour 스크립트에 변경되지 않는 데이터를 저장하는 프리팹이 있는 프로젝트의 경우 유용합니다. 이러한 프리팹을 인스턴스화할 때마다 프리팹에 이 데이터의 자체 사본이 생성되는데, 이와 같은 방법을 사용하여 중복 데이터를 저장하는 대신 ScriptableObject를 이용하여 데이터를 저장한 다음 모든 프리팹의 레퍼런스를 통해 액세스할 수 있습니다. 즉, 메모리에 데이터 사본을 하나만 저장합니다.

MonoBehaviour와 마찬가지로 ScriptableObject는 기본 Unity 오브젝트에서 파생되나, MonoBehaviour와는 달리 게임 오브젝트에 ScriptableObject를 연결할 수 없으며 대신 프로젝트의 에셋으로 저장해야 합니다.

에디터 사용 시, ScriptableObject에 데이터를 저장하는 작업은 편집할 때나 런타임에 가능합니다. 이는 ScriptableObject가 에디터 네임스페이스와 에디터 스크립팅을 사용하기 때문입니다. 배포된 빌드에서는 ScriptableObject를 사용하여 데이터를 저장할 수 없으나, 개발 시 설정한 ScriptableObject 에셋의 저장된 데이터를 사용할 수 있습니다. 에디터 툴에서 에셋 형태로 ScriptableObject에 저장한 데이터는 디스크에 작성되므로 세션 간에도 그대로 유지됩니다.

ScriptableObject 사용하기

ScriptableObject의 주요 사용 사례는 다음과 같습니다.

  • 에디터 세션 동안 데이터 저장 및 보관
  • 데이터를 프로젝트의 에셋으로 저장하여 런타임 시 사용

ScriptableObject를 사용하려면 Assets 폴더에 스크립트를 생성하고 ScriptableObject 클래스에서 상속하도록 해야 합니다. CreateAssetMenu 속성을 사용하면 더욱 간편하게 클래스를 이용하여 커스텀 에셋을 생성할 수 있습니다. 다음 예를 참조하십시오.

using UnityEngine;

[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/SpawnManagerScriptableObject", order = 1)]
public class SpawnManagerScriptableObject : ScriptableObject
{
    public string prefabName;

    public int numberOfPrefabsToCreate;
    public Vector3[] spawnPoints;
}

Assets 폴더의 상기 스크립트를 이용하여 Assets > Create > ScriptableObjects > SpawnManagerScriptableObject 로 이동하여 ScriptableObject의 인스턴스를 생성할 수 있습니다. 새 ScriptableObject 인스턴스에 알아볼 수 있는 이름을 지정하고 값을 변경합니다. 이러한 값을 사용하려면 ScriptableObject를 참조하는 새로운 스크립트를 만들어야 합니다(이 경우 SpawnManagerScriptableObject). 다음 예를 참조하십시오.

using UnityEngine;

public class Spawner : MonoBehaviour
{
    // The GameObject to instantiate.
    public GameObject entityToSpawn;

    // An instance of the ScriptableObject defined above.
    public SpawnManagerScriptableObject spawnManagerValues;

    // This will be appended to the name of the created entities and increment when each is created.
    int instanceNumber = 1;

    void Start()
    {
        SpawnEntities();
    }

    void SpawnEntities()
    {
        int currentSpawnPointIndex = 0;

        for (int i = 0; i < spawnManagerValues.numberOfPrefabsToCreate; i++)
        {
            // Creates an instance of the prefab at the current spawn point.
            GameObject currentEntity = Instantiate(entityToSpawn, spawnManagerValues.spawnPoints[currentSpawnPointIndex], Quaternion.identity);

            // Sets the name of the instantiated entity to be the string defined in the ScriptableObject and then appends it with a unique number. 
            currentEntity.name = spawnManagerValues.prefabName + instanceNumber;

            // Moves to the next spawn point index. If it goes out of range, it wraps back to the start.
            currentSpawnPointIndex = (currentSpawnPointIndex + 1) % spawnManagerValues.spawnPoints.Length;

            instanceNumber++;
        }
    }
}

위의 스크립트를 의 게임 오브젝트에 연결합니다. 그런 다음 인스펙터에서 Spawn Manager Values 필드를 새로 설정한 SpawnManagerScriptableObject로 설정합니다. Entity To Spawn 필드를 Assets 폴더의 아무 프리팹으로 설정하고, 에디터의 Play 를 클릭합니다. Spawner에서 참조한 프리팹이 SpawnManagerScriptableObject.ableObject-derived class에서 설정한 설정으로 인스턴스화된 것을 확인할 수 있습니다. CreateAssetMenu 속성을 사용하여 원하는 클래스를 사용해 커스텀 에셋을 간편하게 생성할 수 있습니다.

팁: 인스펙터에서 ScriptableObject 레퍼런스로 작업할 때 레퍼런스 필드를 더블 클릭해서 ScriptableObject의 인스펙터를 열 수 있습니다. 또한 인스펙터가 나타내는 데이터의 관리에 도움이 되도록 모양을 정의해 커스텀 에디터를 만들 수도 있습니다.


스트리밍 에셋
고급 에디터 토픽