Unity가 직렬화를 사용하는 방법
More details about how serialization works in Unity.
읽는 시간 3분최근 업데이트: 한 달 전
저장 및 로드
Unity는 직렬화를 사용하여 씬, 에셋, 에셋 번들을 장치의 메모리에 저장하고 로드합니다. 여기에는 MonoBehaviour 컴포넌트 및 ScriptableObjects 같은 자체 스크립팅 API 오브젝트에 저장된 데이터가 포함됩니다.
Unity 에디터의 많은 기능은 핵심 직렬화 시스템을 기반으로 제작되었습니다. 특히 직렬화에 주의해야 할 두 가지 사항은 인스펙터 창과 핫 리로드입니다.
인스펙터 창
인스펙터 창에는 검사된 오브젝트의 직렬화된 필드 값이 표시됩니다. 인스펙터에서 값을 변경하면 인스펙터는 직렬화된 데이터를 업데이트하고 검사한 오브젝트를 업데이트하는 역직렬화를 트리거합니다.
빌트인 Unity 오브젝트와 스크립팅 오브젝트(예: MonoBehaviour 파생 클래스) 모두 동일하게 적용됩니다.
Unity는 인스펙터 창에서 값을 보거나 변경할 때 C# 프로퍼티 getter와 setter를 호출하지 않습니다. 대신 Unity는 직렬화된 지원 필드에 직접 액세스합니다.
핫 리로드
스크립트 코드의 핫 리로드는 에셋 데이터베이스 새로 고침의 일환으로 수행됩니다. 이는 에디터 실행 중에 다시 시작하지 않고 코드 변경 사항을 직접 다시 로드하고 적용하는 프로세스를 말합니다. 자세한 내용은 에셋 데이터베이스 새로 고침 및 핫 리로드를 참조하십시오.
참고: 핫 리로드는 특별한 직렬화 사례입니다. 다른 직렬화 사례와 달리, Unity는 다시 로드할 때 SerializeField 속성이 없는 경우에도 기본으로 비공개 필드를 직렬화합니다.
Unity가 스크립트를 리로드하면 Unity는 다음을 수행합니다.
-
Unity는 로드된 모든 스크립트의 모든 변수를 직렬화하고 저장합니다.
-
Unity는 원래의 사전 직렬화 값에 다음과 같이 변수를 복원합니다.
- Unity는 변수에 속성이 없는 경우에도 직렬화 요구 사항을 충족하는 모든 변수(비공개 변수 포함)를 복원합니다. 예를 들어 스크립트에서 다시 로드한 후 레퍼런스가 null이 되도록 하려면 Unity가 비공개 변수를 복원하지 못하도록 해야 할 때가 있습니다. 이 경우에는
[SerializeField]속성을 사용합니다.[field: NonSerialized] - Unity는 정적 변수를 복원하지 않으므로 스크립트를 리로드한 후에도 유지해야 하는 상태에는 정적 변수를 사용하지 마십시오. 리로드 프로세스가 이를 폐기합니다.
- Unity는 변수에
프리팹
프리팹은 하나 이상의 게임 오브젝트 또는 컴포넌트의 직렬화된 데이터입니다. 프리팹 인스턴스에는 프리팹 소스와 수정 목록에 대한 레퍼런스가 모두 포함되어 있습니다. 수정은 Unity가 해당 프리팹 인스턴스를 생성하기 위해 프리팹 소스에 수행해야 하는 작업입니다.
프리팹 인스턴스는 Unity 에디터에서 프로젝트를 편집할 때만 존재합니다. Unity 에디터는 게임 오브젝트를 두 세트의 직렬화 데이터(프리팹 소스와 프리팹 인스턴스의 수정 사항)로부터 인스턴스화합니다.
인스턴스화
프리팹이나 게임 오브젝트처럼 씬에 존재하는 요소에서 를 호출하면 Unity는 다음을 수행합니다.
Instantiate- Unity는 이를 직렬화합니다. 이 작업은 런타임 시점과 에디터에서 모두 발생합니다. Unity는 에서 파생되는 모든 것을 직렬화할 수 있습니다.
UnityEngine.Object - Unity는 새로운 게임 오브젝트를 생성하고 새로운 게임 오브젝트에 데이터를 역직렬화합니다.
- Unity는 다른 배리언트에서 동일한 직렬화 코드를 실행하여 참조하는 다른 를 보고합니다. 참조된 모든
UnityEngine.Objects가 Unity가 인스턴스화하는 데이터의 일부인지 확인합니다. 레퍼런스가 텍스처와 같은 외부 요소를 가리키는 경우 Unity는 해당 레퍼런스를 그대로 유지합니다. 레퍼런스가 자식 게임 오브젝트와 같은 내부 요소를 가리키는 경우 Unity는 해당 복사본에 대한 레퍼런스를 패치합니다.UnityEngine.Objects
사용되지 않는 에셋 언로드
EditorUtility.UnloadUnusedAssetsImmediateUnityEngine.Objects에디터와 런타임 직렬화의 차이
대부분의 직렬화는 에디터에서 이루어지지만 역직렬화는 주로 런타임 시 이루어집니다. Unity는 일부 기능만 에디터에서 직렬화하고, 에디터와 런타임 시 다른 기능을 모두 직렬화할 수 있습니다.
기능 | 에디터 | 런타임 |
|---|---|---|
| Assets in Binary Format | 읽기/쓰기 지원됨 | 읽기 지원됨 |
| Assets in YAML format | 읽기/쓰기 지원됨 | 미지원 |
| Saving scenes, prefabs and other assets | 플레이 모드가 아닌 경우 지원됨 | 미지원 |
| Serialization of individual objects with JsonUtility | JsonUtility로 읽기/쓰기 지원 EditorJsonUtility로 오브젝트 추가 유형 지원 | JsonUtility로 읽기/쓰기 지원 |
| SerializeReference | 지원됨 | 지원됨 |
| ISerializationCallbackReceiver | 지원됨 | 지원됨 |
| FormerlySerializedAs | 지원됨 | 미지원 |
오브젝트에는 다음과 같이 UNITY_EDITOR 스크립팅 심볼 내에서 필드를 선언하는 경우처럼 에디터만 직렬화할 수 있는 추가 필드가 있을 수 있습니다.
public class SerializeRules : MonoBehaviour{#if UNITY_EDITORpublic int m_intEditorOnly;#endif}
이전 예시에서 필드는 에디터에서만 직렬화되며 빌드에 포함되지 않습니다. 이렇게 하면 빌드에서 에디터에 필요한 데이터만 생략하여 메모리를 절약할 수 있습니다. 이 필드를 사용하는 코드는 빌드 시 클래스를 컴파일할 수 있도록 블록 내에서 조건부로 컴파일해야 합니다.
m_intEditorOnly#if UNITY_EDITOR에디터는 Unity가 런타임 시에만 직렬화하는 필드가 있는 오브젝트를 지원하지 않습니다(예: UNITY_STANDALONE 지시문 내에 필드를 선언하는 경우).