샘플 프로젝트 (AdventureTutorial)
Scene.unity 파일에 직렬화하기
Scriptable Object의 인스턴스를 .asset 파일 대신에 Scene.unity 파일에 직렬화 해보자.
'Interactable' 개체는 ConditionCollection 배열(컨테이너)을 프로퍼티로 갖는데, 씬에서 생성된 인스턴스를 저장하고 참조하는데 쓰인다.
ConditionCollection은 다시 Condition 배열(컨테이너)을 프로퍼티로 갖는다.
Scene에서 이 ScriptableObejct의 인스턴스는 어떻게 직렬화 될까?
Scene.unity 파일에는 씬에 배치된 개체들의 Transform, MonoBehaviour 스크립트 등의 Inspector 내용이 직렬화되어 저장된다.
Study.unity 파일을 열어보면 'PrefabInstance'란 형태로 Interactable 개체의 프로퍼티들을 볼 수 있다.
해당 개체의 MonoBehaviour 스크립트는 'conditionCollection'이란 필드가 정의됐다.
이 필드의 value로 인스턴스 참조값이 들어있는데 fileID 형태로 되어있다.
해당 file ID에 해당하는 직렬화 항목을 찾아 볼 수 있다.
Condition Collection의 인스턴스는 'requiredConditions'이란 필드를 갖는데 이 필드 또한 fileID 값을 갖는다.
즉, MonoBehaviour의 각 프로퍼티의 참조 값 자격으로 Scriptable Object의 인스턴스가 fileID형태로 저장되는 것을 볼 수 있다.
m_script 필드의 guid는 각 인스턴스의 스크립트 .meta파일의 guid와 일치한다.
.Prefab 파일에는 직렬화 되지 않는다.
프리팹은 .asset파일이 아닌, 인스턴스 참조를 불러오지 못한다.
.Prefab 파일은 Scriptable Object의 인스턴스를 fileID로 직렬화 하지 못하기 때문이다.
그래서 프리팹에서 생성된 Scriptable Object 인스턴스는 Null을 반환해 버린다.
이는 Null 참조 발생 원인이 되므로 Null 체크 구문을 통해 방어 코드를 작성해야한다.
씬에서 생성된 SO 인스턴스는 씬 파일에 저장됐기 때문에 참조가 유지된다.
프리팹에서 생성된 SO 인스턴스는 프리팹 파일에 저장되지 못하고 null을 반환한다.
"1개로 늘어난 컨테이너 길이를 다시 조정할 필요가 있다. 컨테이너 길이로 처리가 진행되기 때문."
컨테이너 헬퍼 함수 API
1
2
3
4
5
6
|
// 해당 인덱스에 빈 요소 삽입
SerializedProperty.InsertArrayElementAtIndex(array.arraySize)
// 해당 인덱스의 요소 가져오기 & 해당 요소 프로퍼티(get;set;)
SerializedProperty.GetArrayElementAtIndex(array.arraySize).objectReferenceValue
// 해당 인덱스의 요소 제거
SerializedProperty.DeleteArrayElementAtIndex(index)
|
Array와 List 등 컨테이너형 프로퍼티를 다룰 때 사용한다.
https://docs.unity3d.com/ScriptReference/SerializedProperty.html
'Unity > 스크립터블오브젝트' 카테고리의 다른 글
Scriptable Object - 응용: EditorWithSubEditors, 확장 메서드 (11) (2) | 2020.06.08 |
---|---|
Scriptable Object - 응용: Interactable, 커스텀 에디터 (10) (0) | 2020.06.08 |
Scriptable Object - 응용: Dual Serialization, 세이브 & 로드 (8) (1) | 2020.06.03 |
Scriptable Object - 응용: Destructible, Brain(AI) (7) (0) | 2020.06.02 |
Scriptable Object - 응용: 오디오 이벤트, 프로퍼티 드로워, 커스텀 에디터 (6) (0) | 2020.06.01 |
댓글