본문 바로가기
게임개발/Unity

[Unity] ScriptableObject

by 개발도사(진) 2024. 6. 9.

공식 홈페이지에 따르면, ScriptableObject는 클래스 인스턴스와는 별도로 데이터를 저장할 수 있는 데이터 컨테이너이며, 그 목적은 사본이 생성되는 것을 방지하여 메모리 낭비를 줄이는 것이다.

 

처음 이런 설명을 들었을 때는 잘 와닿지 않았는데, 다음 예시를 생각해 보자.

 

가령, 과일 아이템들을 만드려 하고, 과일 아이템은 각자 이름, 색깔, 가격, 아이템 등급 등의 정보를 지닌다고 하자. 이 때, 같은 종류의 과일 아이템끼리는 이 값들을 모두 동일하게 공유할 것이다. 이 값들을 ScriptableObject로 만들어 모든 사과 아이템들이 참조할 수 있는 reference로 삼는 것이다. 

 

예시를 통해 살펴보도록 한다. 먼저, ScriptableObject를 생성한다.

[CreateAssetMenu(fileName = "ItemScriptableObject", menuName = "ScriptableObject/Item")]
public class ItemScriptableObject: ScriptableObject
{
    public string itemName;
    public int itemLev;
    public int itemCost;
    public Color itemColor;
}

CreateAssetMenu를 통해 앞으로 이 ScriptableObject를 project view에서 직접 생성할 수 있다. fileName은 이 ScriptableObject가 생성되었을 때의 기본 이름, menuName은 project view에서 직접 이 ScriptableObject를 생성할 때의 경로가 된다.

 

이후, 다음과 같이 해당 ScriptableObject의 정보를 이용한 Item class를 정의한다.

public class Item: MonoBehaviour
{
    public ItemScriptableObject itemScriptableObject;

    public void Initialize(ItemScriptableObject itemScriptableObject)
    {
        this.itemScriptableObject = itemScriptableObject;

        var renderer = GetComponent<Renderer>();
        renderer.material.color = itemScriptableObject.itemColor;
    }
}

 

이후 각 Item에 사용될 data를 담고 있는 ScriptableObject를 생성한 후, Item을 생성할 ItemGenerator Class에 다음과 같이 할당해 준다.

 

이후 다음 코드를 실행하면 원하는 정보를 담고 있는 Item 3개가 생성된다. 

public class ItemGenerator: MonoBehaviour
    {
        public ItemScriptableObject[] itemScriptableObjects;

        void Start()
        {
            for (int i = 0; i < 3; i++)
            {
                var newGameObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                var newItemScipt = newGameObject.AddComponent<Item>();

                newItemScipt.Initialize(itemScriptableObjects[i]);

                newGameObject.transform.position = new Vector3(i * 3, 0, 0);
            }
        }
    }

 

만약 여기서 해당 아이템들을 각각 100개씩 생성했다고 생각해 보자. 일반적인 Prefab을 통해 접근하였다면 각 아이템마다 itemName, itemLev, itemCost... 등의 값을 가지고 있었을 것이고, 변수 각각이 모두 메모리 공간을 잡아먹었을 것이다. 그러나 ScriptableObject를 활용하였다면, 아이템을 몇 개를 생성하든 데이터 공간은 ScriptableObject가 사용하는 만큼만 필요할 것이다. 

'게임개발 > Unity' 카테고리의 다른 글

[Unity] JSON 이용하여 데이터 저장하기  (0) 2024.08.28
[Unity] GameObject의 이동(기본)  (0) 2024.06.10
[Unity] 게임오브젝트의 회전  (1) 2024.06.08
[Unity] Unity Event  (0) 2024.06.07
[Unity-UI] Canvas - Render Mode  (1) 2023.11.12