본문 바로가기
유니티/중급

유니티 스크립터블 오브젝트( ScriptableObject )

by 노튜 2021. 1. 5.
728x90

 

1. ScriptableObject

 

스크립터블 오브젝트(ScriptableObject)는 대량의 데이터를 저장할 수 있는 데이터 컨테이너이며, 미리 정의된 데이터를 공유하여, 메모리의 사용을 줄일 수 있도록 구현되어 있다. 

 스크립터블 오브젝트는 프로젝트를 빌드하기 전 에디터 모드에서 수정 및 정의가 가능하도록 설계되어 있다. 유니티 프로그램 안에서 플레이 모드 런타임 시에는 수정이 가능하다. 그러나 빌드된 후에는 수정을 할 수 없다. 물론, 기타 여러 가지 방법을 사용하면 가능할 수 있다. 인터넷 상에서 스크립터블 오브젝트를 사용하여 인벤토리 시스템을 구현하는 것을 본 적이 있다. 실제 테스트를 해보지는 않았다. 그렇지만 인벤토리 시스템과 같이 실시간으로 데이터를 수정 및 저장하는 부분은 C# class를 사용하여 데이터를 정의하고 JSON을 사용하여 저장 및 불러오기 등의 기능은 쉽게 구현이 가능하다.        

 

요약하면, 스크립터블 오브젝트는 에디터 모드에서는 수정 가능 데이터, 빌드 이후에는 변경 불가능한 데이터이다.

 

아래의 프로그램은 Start() 함수가 호출되면 스크립터블 오브젝트의 변수 값을 출력하고, 10초 후에 값을 변경하고 이를 출력하는 예제 프로그램이다. 

실행해 값이 변경되면 프로그램을 종료하고, 다시 프로그램을 실행하면 변경되지 않은 값이 출력되는 것을 볼 수 있다. 

   

New Unity Project.exe
0.61MB

 

       

그러면 스크립터블 오브젝트는 어디에 사용해야 하는가? 유니티 매뉴얼에서는 아래의 두 가지를 대표적 사례로 제시하고 있다.

 

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

 

개발자가 원하는 곳에 스크립터블 오브젝트를 사용하여 프로젝트를 구현하면 된다. 본인은 프리팹이나 에셋을 공유, 속성 값의 변경이 필요하지 않은 데이터들을 공유하는데 스크립터블 오브젝트를 사용하고 있다. 

 

 

2. ScriptableObject 정의 및 생성

 

2.1 정의

스크립터블 오브젝트를 상속받아 필요한 스크립터블 오브젝트를 정의한다.

MyScriptableObject : ScriptableObject

 

※ 스크립터블 오브젝트는 MonoBehaviour와 다르므로, Start(), Update() 등을 사용할 수 없다.

 

2.2 메뉴를 사용하여 생성

스크립터블 오브젝트를 정의하고 에디터 모드에서 생성한다. 스크립터블 오브젝트의 클래스 위쪽에 다음의 코드를 입력한다. 

[CreateAssetMenu(fileName = "파일이름 ", menuName = "메뉴이름", order = int값)]
  • fileName : 처음 생성 시 파일의 이름을 정의한다. 
  • menuName : 메뉴에 출력할 이름을 정의한다.  
  • order : 동일한 계층 구조에서 보이는 순서를 정의한다. 정의하지 않으면, 유니티의 기본 순서로 정렬한다. 

 

Script를 생성하고, 아래와 같은 형식으로 스크립터블 오브젝트를 정의한다.

using UnityEngine;

[CreateAssetMenu(fileName ="MyScriptable", menuName ="A/A", order = 3)]
public class MyScriptableObject : ScriptableObject
{
    public string testName;
    public int count;
    public GameObject gameObject;
}

 

프로젝트 창에서 마우스 우클릭하여 아래와 같이 생성한다.

또한, 메인 메뉴를 선택하여 생성이 가능하다.

Assets → Create menuName Directory

 

 

Project View -> Right Mouse Button -> ...

 

CreateAssetMenu의 fileName으로 아래 이미지처럼 스크립터블 오브젝트가 생성된다.

생성된 스크립터블 오브젝트의 이름은 의도에 맞게 변경하여 사용한다.

 

FileName

 

 

 

2.3 런타임 생성

스크립터블 오브젝트는 런타임 시에 생성이 가능하다. 그러나 스크립터블 오브젝트가 프로젝트 폴더에 생성되지 않는다. 즉, 저장이 되지 않는다. 

 

using UnityEngine;
using UnityEngine.UI;

public class CreateMyScriptables : MonoBehaviour
{
    public Text text;
    public MyScriptableObject myScriptableObject;
    // Start is called before the first frame update
    void Start()
    {
        myScriptableObject =  ScriptableObject.CreateInstance<MyScriptableObject>();
        myScriptableObject.testName = "Test";

        text.text = myScriptableObject.testName;
    }
}

 

 

3. 스크립트 사용 예제

위의 예제 프로젝트에 사용한 스크립트이다. 

 

using UnityEngine;

[CreateAssetMenu(fileName ="MyScriptable", menuName ="MyScriptableObject")]
public class MyScriptableObject : ScriptableObject
{
    public string testName;
}

 

using UnityEngine;
using UnityEngine.UI;

public class TestScriptableObject : MonoBehaviour
{
    public Text text;
    public MyScriptableObject myScriptableObject;
    
    float myTime = 10.0f;
    
    // Start is called before the first frame update
    void Start()
    {
        text.text = myScriptableObject.testName;
    }

    // Update is called once per frame
    void Update()
    {
        myTime -= Time.deltaTime;

        if (myTime < 0)
        {
            myScriptableObject.testName = "Changed";
            text.text = myScriptableObject.testName;
        }
    }

    public void OnCloseButtonClicked()
    {
        Application.Quit();
    }
}

 

 

4. 참조

 

https://docs.unity3d.com/kr/2020.2/Manual/class-ScriptableObject.html

 

ScriptableObject - Unity 매뉴얼

ScriptableObject는 클래스 인스턴스와는 별도로 대량의 데이터를 저장하는 데 사용할 수 있는 데이터 컨테이너입니다. ScriptableObject의 주요 사용 사례 중 하나는 값의 사본이 생성되는 것을 방지하

docs.unity3d.com

 

728x90