티스토리 뷰
Unity 개발에 있어 핵심요소중 하나는 직렬화시스템이라고 할 수 있기에 정리해본다.
## 직렬화(Serialization)
- 컴퓨터 과학의 Data Storage 측면에서 데이터구조나 객체 상태를 다양한 플랫폼 또는 전송간에도 재구성(역직렬화;Deserialization)할 수 있는 포맷(byte stream)으로 변환하는 프로세스
- 직렬화 방식은 컴퓨터가 처리하기 쉬운 이진(binary)방식 byte stream과 사람이 처리하기 쉬운 text방식 byte stream이 있다(e.g. 이미지에 사용되는 이진방식포맷, 네트워크간 데이터 전달에 사용되는 JSON같은 text방식포맷)
- 컴퓨팅과 직렬화는 떼어 놓을 수 없는 관계
- 데이터 지속성(Persistence)를 위해 저장장치 또는 DB에 저장(직렬화) 및 로드(역직렬화)
- Network간 데이터 전달(e.g. JSON, XML)
- Unity에서는 YAML형식으로 Scene, Prefab, ScriptableObject 등을 직렬화
- Domain간 데이터 전달(e.g. C# <-> Java, Unity Editor <-> Unity Player(play mode), App <-> CDN, etc)
컴퓨팅 전반적인 과정에 직렬화가 대부분 사용되며 WPF의 XAML UI편집툴인 Blend처럼 WYSIWYG에도 직렬화가 사용되기도 한다. Unity Editor에서 WYSIWYG이 가능한것도 마찬가지로 이런 직렬화를 사용하기 때문이다(Unity Core Serialization System). Unity Editor의 인스펙터는 직렬화된 데이터(field)들과 바인딩 되어있기 때문에 이를 통해 수정된 각종 필드값은 직렬화된 데이터라서 Editor 종료후 프로젝트를 다시 열어도 동일한 상태로 역직렬화된다. 파워포인트에 도형들을 이리저리 편집했다가 저장 후 다시 불러오면 편집사항이 그대로 있는것과 비슷하다.
즉, Inspector에서 편집하는것은 직렬화된 데이터이므로 원본 데이터(e.g. C# Script)와는 별개이며, Inspector에서 직렬화된 필드를 수정해도 직렬화된 스트림(Scene.asset)만 수정되므로 원본에는 영향을 끼치지 않는다. 그리고 에디터 재시작, Play Mode, Runtime같은 역직렬화 과정에서 닷넷어셈블리의 객체정보로부터 생성되는 객체 인스턴스는 직렬화된 스트림(e.g. 씬 : *.unity)에 저장되어있던 객체의 상태(field)값들로 overwrite되어 역직렬화가 완료된다.
Play Mode에서 수정한 설정값들이 Play Mode 종료시 초기화되는것도 직렬화 시스템과 연관이 있다. Play Mode는 Unity Editor 프로세스의 하위 Domain(닷넷/모노의 AppDomain)으로 생성되고 실행되며, 이들 Domain간 통신이 직렬화를 통해 이루어지기 때문이다. (Domain 및 Scene 재로드 여부는 Project Settings에서 설정가능) 즉, Play Mode는 별개의 실행앱으로 봐도 무방하다.
그렇다면 Unity에서는 왜 직렬화를 사용할까?
- Scene View의 WYSIWYG 및 개발데이터의 효율적인 영속성(Persistence)을 위해
- Edit time의 Play Mode를 통한 테스트를 용이성을 위해
- script를 재컴파일 하지 않고도 각종 직렬화된 값들을 edit time에 실시간 수정 및 반영(e.g. inspector를 통한 수정)
- 다양한 플랫폼에서 에디터 동작(e.g. Windows, Linux, Mac). 즉, cross-platform지원
즉, 게임개발 workflow에 효율적이다.
`Unity.Object`를 상속받은 객체들은 직렬화되며, `Instantiate()` static method를 통해 런타임에 역직렬화 가능하다. (직렬화 관련 API들이 `Unity.Object`에 정의되어 있음) 직렬화 수행을 위한 규칙을 충족한 필드들이 직렬화 되며 `Serializable` attribute 등의 API를 사용해 custom class 등도 직렬화 가능하다.
## Prefab과 ScriptableObject
- Scene
- 장면의 직렬화된 GameObject, Component 등이 적재되는 구조체 asset개체(확장자는 *.unity)
- Prefab
- 재사용성을 위해 모듈화 및 직렬화시킨 하나 이상의 GameObject 및 컴포넌트집합 asset개체
- Unity는 Struct타입인 Scene에 GameObject들이 포함되는 구조인데 중복 등으로 재사용이 필요한 GameObject들은 Prefab화 시켜서 GameObject를 찍어내는 템플릿처럼 사용한다
- 즉, Scene.asset 직렬화스트림의 필요한 부분을 모듈화시켜 쪼갠다고 생각하면 된다(확장자는 *.prefab)
- ScriptableObject
- 메모리 효율성 및 데이터 관리 효율성을 위해 모듈화 및 직렬화시킨 데이터집합 asset개체
- 예를들어 Prefab이 인스턴스화 될때 내부 필드들의 사본도 각각 메모리에 올라가는데, 이를 ScriptableObject로 모듈화시켜서 참조하게 하면 메모리 관리에 효율적
- 즉, Scene에 올라가는 GameObject(or Prefab)의 필요한 데이터부분만 다시 모듈화시켜 쪼갠다고 생각하면 된다(확장자는 *.asset)
요약하면 Prefab은 GameObject를 직렬화 시킨거고 ScriptableObject는 GameObject의 데이터(field) 집합을 직렬화 시킨것. 핵심은 직렬화 데이터의 유형 차이.
이상의 유니티 코어 직렬화시스템 개념들을 잘 이해하고 있다면 Unity Editor를 통해 개발하고 Unity Player를 통해 런타임 동작을 테스트하는데 큰 도움이 된다. 결국 핵심은 직렬화.
## References
https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/concepts/serialization/
https://learn.microsoft.com/ko-kr/dotnet/framework/app-domains/use
https://docs.unity3d.com/kr/2021.2/Manual/AssetWorkflow.html
https://docs.unity3d.com/kr/current/Manual/script-Serialization.html#HowUnityUsesSerialization
https://blog.unity.com/technology/serialization-in-unity
https://docs.unity3d.com/kr/current/Manual/ConfigurableEnterPlayModeDetails.html
'Game > Fundamental' 카테고리의 다른 글
벡터(vector), 스칼라(scala), 속도(velocity), 속력(speed) 그리고 오일러(euler), 사원수(quaternion) (0) | 2022.10.14 |
---|
- Total
- Today
- Yesterday
- async
- 싱글톤
- Python
- Scraping
- VS2022
- C#
- initialize
- Debug
- Custom Package
- 닷넷
- logging
- Singleton
- coroutine
- 코루틴
- framework
- RuntimeInitializeOnLoadMethod
- git
- await
- Addressables
- Visual Studio Code
- vscode
- 유니티
- unity
- .net
- 비동기
- 환경설정
- selenium
- github
- gcp
- firestore
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |