03. ScriptableObject 의 데이터 공유와 관련하여 - gryphus11/ScriptableObject GitHub Wiki
-
ScriptableObject 는 Scene, Prefab 이외의 Unity 에디터에서 값을 조정하는 것이 가능한 오브젝트입니다. Unity 에디터 상에서 값을 조정하는 경우, ScriptableObject 와 Scene, Prefab 을 사용하면 쉽게 값의 조정 및 이용이 가능합니다.
-
ScriptableObject 의 에셋은 [에셋] 인 동시에 [인스턴스] 이기도 합니다. 이는 조금 재미있는 특징을 가집니다. 예를들어, 복수의 Prefab 과 Scene 에서 참조되는 경우에도, 임의로 복제되지 않고 단일 인스턴스로 유지됩니다.
Scene A 와 Scene B 라는 두개의 Scene 이 있습니다. 각각 OBJ1 과 OBJ2 라고 하는 오브젝트를 가지고 있습니다. 여기서 OBJ1 과 OBJ2 가 같은 ScriptableObject 를 참조하는 경우, OBJ1 과 OBJ2 이 참조하는 ScriptableObject 는 동일한 것 입니다.
이 구조를 이용하면 Find 나 Static 등을 일절 사용하지 않고 동적으로 컴포넌트와 컴포넌트를 연결할 수 있습니다.

[일본어] 버튼을 누르면 소리가 나온다... 를, 가능한한 코드를 사용하지 않고 구현
ScriptableObject 는 에셋이며 인스턴스이다.
-
-
마음 먹으면 Static 이나 Singleton 의 대용이 가능하다 생각합니다. 굳이 차이점을 적자면
- Find 나 Static 을 사용하지 않고 오브젝트를 참조 가능
- 에디터에서 값을 조정 가능
- 인스턴스의 파괴가 가능
- UnityEvent 베이스로 여러가지 가능
-
코드에 ScriptableObject 를 참조하는 멤버를 두어 참조하는 방법
작성한 코드에 생성한 ScriptableObject 를 등록해 두면 컴포넌트로 등록할 때에 자동으로 참조됩니다.
-
Resources 로 부터 불러들인 경우도 동일하게 단일 인스턴스로 다루어 집니다. 예를들어, 서로 다른 코드에서 Resources.Load 로 ScriptableObject 를 로드했지만, 같은 인스턴스이기 때문에 어느 한쪽에서 값을 변경하면 다른쪽의 값도 변경이 됩니다. Resources 로 부터 로드한 인스턴스는 파괴되지 않는 한 동일 이라 알고 있습니다.
ScriptableObject 에 를 코드에서 참조
ScriptableObject 를 Resources 로부터 Load
-
에셋의 인스턴스를 사용해 데이터를 공유했지만, 사실 이 방법은 한가지 문제가 있습니다. 에셋의 값을 갱신한다는 것은, 파일도 갱신된다는 것이라는 점입니다. 바꾸어 말하면, Scene 의 재생을 종료해도 수치가 원래대로 돌아가지 않습니다.
Scene 이 한번 정지되었음에도 불구하고, 다시 재생하면 도중의 수치가 가산되어집니다. 플레이어 에서는 문제가 없지만, 에디터에서 발생하는 문제입니다.

이것을 회피하기 위한 방법으로는 private 로 [SerializeField] 가 아닌 필드나, 프로퍼티를 사용하여 OnEnable 에서 초기화 수행하는 방식입니다. 자세히 말하자면, ScriptableObject 에 Inspector 표시용의 값(private)과 실제 게임에서 사용하는 값(프로퍼티)의 2종류를 준비해 OnEnable 타이밍에 초기화 합니다.
다른 방법으로는 ScriptableObject 가 에셋이면서 인스턴스인 점을 이용합니다. 게임의 재생 정지시에 ScriptableObject 를 Unload 해버리면, 재생중에 변경된 값은 없어지게 되어, ScriptableObject 의 값이 파일에 덮어지는 일은 없습니다. 먼저, Scene 의 재생 정지시 자신의 인스턴스를 언로드하는 것과 같은 행동을 가진 ScriptableObject 의 파생클래스를 만듭니다.
이것을 상속하는 것으로, Scene 재생시에 ScriptableObject 의 값이 최후에 Project Save 한 지점까지 값을 되돌립니다.
