UNITY3D : 데이터 시리얼라이제이션 - Serialization 직렬화

Unity 직렬화(Serialization), 왜 중요한 걸까?

“Unity에서 SerializeField를 썼는데 왜 저장이 안 되지?”
“왜 어떤 필드는 인스펙터에 안 보이는 거지?”

Unity에서 직렬화는 단순한 개념 같지만, 생각보다 많은 기능이 이 메커니즘에 의존하고 있어요.
이번 글에서는 Unity의 직렬화 시스템이 어떤 역할을 하는지, 어떤 기준으로 작동하는지를 하나씩 살펴보겠습니다.


Unity에서 직렬화가 중요한 이유

Unity는 직렬화 가능한 필드만 저장하고 표시합니다.
다음과 같은 상황에서 직렬화가 필수적이에요:

사용 상황 설명

인스펙터에 필드를 보이게 하려면 필드는 직렬화되어야 인스펙터에 표시되고 저장됩니다.
씬이나 프리팹에 값이 저장되게 하려면 .unity, .prefab 파일은 직렬화된 데이터만 저장합니다.
ScriptableObject나 SaveData를 사용하려면 재사용/공유 가능한 데이터는 직렬화를 통해 유지됩니다.

Unity 직렬화의 기본 규칙

Unity는 .NET 표준 직렬화 시스템과는 다른, 자체 시스템을 사용합니다.
직렬화되기 위한 조건은 다음과 같습니다:

조건 설명

public 또는 [SerializeField] 인스펙터에 표시되며 저장됨
Unity가 지원하는 타입 int, float, bool, string, Vector3, Color 등
Unity 엔진 객체 GameObject, Transform, MonoBehaviour 등
[System.Serializable] 속성 사용자 정의 클래스 직렬화를 위해 필요
기본 생성자 필수는 아니지만 있는 편이 안정적

참고: ISerializable, [DataContract] 등 C# 표준 직렬화 기능은 Unity에서 무시됩니다.


예시 코드 – 직렬화 가능한 클래스

[System.Serializable]
public class ItemData {
    public string itemName;
    public int itemCount;
}

public class Inventory : MonoBehaviour {
    [SerializeField]
    private ItemData[] items; // 인스펙터에서 보이고 저장됨
}

이런 구조를 사용하면 인스펙터에서 ItemData 배열을 수정하고, 그 값이 씬/프리팹에 저장되도록 할 수 있습니다.


ScriptableObject와 직렬화

ScriptableObject는 에디터 내에서 독립적인 데이터 에셋으로 사용할 수 있고, 내부 필드도 직렬화됩니다.

[CreateAssetMenu(fileName = "New Item", menuName = "Item")]
public class ItemSO : ScriptableObject {
    public string itemName;
    public Sprite icon;
}

ScriptableObject는 여러 오브젝트에서 공통으로 참조할 수 있고, 재사용성과 유지보수성이 뛰어나기 때문에 자주 사용됩니다.


직렬화 vs 메타데이터

개념 설명

직렬화 (Serialization) 객체 상태를 JSON 등으로 변환해 저장하는 과정
메타데이터 (Metadata) 데이터의 구조나 속성, 타입에 대한 정보

Unity의 직렬화 시스템은 내부적으로 메타데이터를 스캔해서 어떤 필드를 저장할지 판단합니다. 예를 들어 아래 클래스의 구조 자체가 하나의 메타데이터가 됩니다:

[System.Serializable]
public class PlayerData {
    public int level;
    public string name;
}

그리고 실제 직렬화된 데이터는 다음과 같은 구조를 가질 수 있어요:

{
  "type": "PlayerData",
  "version": "1.0",
  "data": {
    "level": 3,
    "name": "Jisoo"
  }
}

여기서 "type"과 "version"은 메타데이터이고, "data" 내부는 실제 저장된 값입니다.


Unity의 YAML 포맷과 GUID 시스템

Unity 프로젝트에서 .unity, .prefab 파일을 텍스트 모드로 저장하면 YAML 형식이 사용됩니다.
텍스트 기반 저장 방식은 Git 등의 버전 관리 시스템과 호환성이 좋고, 충돌 해결도 쉬워집니다.

각 에셋은 고유한 GUID를 갖기 때문에, 파일을 다른 폴더로 이동해도 참조가 유지됩니다.
또한 오브젝트 간의 의존성 파악에도 사용됩니다.

 

Unity에서 직렬화를 이해하고 사용하는 것은 단순히 “데이터를 저장하는 방법”을 넘어서, 에디터 기능과 런타임의 모든 흐름을 이해하는 기본이라고 할 수 있습니다.

 

유니티에서는 다음과 같이 에셋에 대한 정보를 설정할 수 있는 탭이 존재 한다.

 

직렬화는 기본적으로 Text로 되어있고 Text방식이여야 나중에 깃허브나 다른곳에서 사용할 때 텍스트 방식이 사용하기 편하기 때문이다.

 

만들어진 씬을 Text 로 열어보면 다음과 같이 YAML 파일의 형식으로 씬이 구현되어있는 것이 확인이 가능하고 해당 오브젝트에 대한 정보들을 확인이 가능합니다

 

각 에셋은 고유한 GUID를 가지고 있으며, 파일 위치가 변경되어도 참조는 유지됩니다.
또한, 에셋 간의 의존성이나 사용 관계를 추적하는 데에도 사용됩니다.

예를 들어, .unity 파일을 텍스트 편집기로 열면 다음과 같이 확인할 수 있습니다:

 

이처럼 Unity는 YAML을 통해 오브젝트 상태를 텍스트로 저장하며, GUID 기반의 에셋 참조 시스템을 통해 안정성을 확보합니다.