Scriptable Object는 클래스의 인스턴스와는 별개로 자료를 저장할 수 있는 데이터 컨테이너입니다. Scrpitable Object는 주로 값의 사본이 생성되는 것을 방지하여 메모리 사용을 줄여줍니다. 예를 들어서 MonoBehaviour 스크립트에 변경되지 않는 데이터를 저장하는 프리팹이 있는 프로젝트의 경우 유용하게 사용됩니다. 프리팹을 인스턴스화 할 때마다 프리팹에 이 데이터 자체의 사본이 생성되는데, 이와 같은 방법을 사용하여 중복 데이터를 저장하는 대신에 Scriptable Object를 이용하여 데이터를 저장한 다음 모든 프리팹을 참조하여 접근할 수 있습니다. 즉, 메모리에 데이터 사본을 하나만 저장하게 되는 것입니다.
Scriptable Object는 유니티 오브젝트에서 파생되지만 MonoBehavior와 달리 게임 오브젝트에 연결할 수 없고 프로젝트의 에셋으로 사용하게 됩니다.
에디터 사용 시, Scriptable Object에 데이터를 저장하는 작업은 편집할 때나 런타임에 가능합니다. 이는 Scriptable Object가 에디터 스크립팅을 사용하기 때문입니다. 빌드 단계에서는 Scriptable Object를 사용하여 데이터를 저장할 수 없고 사용만 가능합니다. 에디터 툴에서 에셋 형태로 저장한 Scirptable Object 데이터는 디스크에 저장되서 세션 간에도 유지됩니다.
이제 간단한 예제로 이해를 해보겠습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObject/SpawnManagerScriptableObject", order = 1)]
public class SpawnManagerScriptableObject : ScriptableObject
{
public string prefabName;
public int numberOfPrefabsToCreate;
public Vector3[] spawnPoints;
}
우선 데이터 컨테이너를 만들어주기 위해 MonoBehaviour 대신 Scirptable Object를 상속합니다. 이후 간편한 데이터 편집을 위해서 Create Asset Menu 속성을 사용해 Assets > Create > ScriptableObjects > SpawnManagerScriptableObject 경로로 인스턴스를 생성할 수 있게 만들어줍니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Spawner : MonoBehaviour
{
public GameObject entityToSpawn;
public SpawnManagerScriptableObject spawnManagerValues;
int instanceNumber = 1;
private void Start()
{
SpawnEntities();
}
private void SpawnEntities()
{
int currentSpawnPointIndex = 0;
for (int i = 0; i < spawnManagerValues.numberOfPrefabsToCreate; i++)
{
GameObject currentEntity = Instantiate(
entityToSpawn,
spawnManagerValues.spawnPoints[currentSpawnPointIndex],
Quaternion.identity);
currentEntity.GetComponentInChildren<Text>().text = spawnManagerValues.prefabName;
currentEntity.name = spawnManagerValues.prefabName + instanceNumber;
/* Scriptable Object의 데이터 수정 환경 테스트 */
spawnManagerValues.prefabName = "TEST";
currentSpawnPointIndex = (currentSpawnPointIndex + 1) % spawnManagerValues.spawnPoints.Length;
instanceNumber++;
}
}
}
이제 만들어둔 Scriptable Object 데이터를 사용할 수 있는 스크립트를 만들어 줍니다. SpawnManagerScriptableObject 인스턴스에서 설정해둔 Prefab을 설정한 위치에서 원하는 개수만큼 생성하는 스크립트입니다. 중간에 Scriptable Object의 수정 환경 테스트를 위해서 spawnManagerValues.prefabName = "TEST"; 의 코드를 삽입했습니다.
이제 실제로 Scriptable Object 인스턴스를 생성하고 테스트를 진행하겠습니다. 처음은 Scriptable Object의 인스턴스를 생성하고 원하는 대로 데이터를 저장하면 됩니다. (에디터 상의 데이터 저장)
이후 플레이 버튼을 눌러 테스트를 진행하면 아래와 같은 형태로 오브젝트들이 구성됩니다.
위에서 코드 중간에 Scriptable Object의 변수인 prefabName을 런타임 도중 수정하도록 코드를 삽입했었습니다. 실제로 테스트를 해보면 런타임 도중 수정이 가능하고 저장 또한 가능하다는 것을 알 수 있습니다.
마지막으로 빌드 단계에서는 데이터의 사용만 가능하고 수정이 불가능한데 실제로 그렇습니다. 테스트를 해보시면 게임 실행 중에는 Cube - Test - Test로 데이터의 일시적인 변경이 가능하나, 다시 게임을 시작하면 Test - Test - Test가 아닌 Cube - Test - Test의 형태로 출력됩니다. 즉, 빌드 단계에서의 데이터의 수정이 불가능합니다.
지금까지 Scirptable Obejct 클래스에 대해서 간단하게 알아보았습니다.
'프로그래밍 > 유니티' 카테고리의 다른 글
[유니티] GetComponentsInChildren 주의점 (0) | 2022.02.02 |
---|---|
[유니티] SerializeField 알아보기 (0) | 2021.02.28 |
[유니티] Editor 관련 자주 사용하는 변수 및 함수 정리 (0) | 2020.12.10 |
[유니티] 유니티 마우스 커서 관련 옵션 (0) | 2020.11.12 |
[유니티] 꼭짓점 스냅핑(Vertex Snapping) 살펴보기 (0) | 2020.07.22 |