Serialization

유니티를 하다보면 Serialization(직렬화)이란 게 익숙하다. 정확히 어떤 개념인지는
몰라도 이것이 inspector 창에 띄우기 위해 필요하다는 것은 안다.

직렬화는 객체의 상태를 저장하거나 전송할 수 있는 형태로 변환하는 과정이다.
반대로 저장된 데이터를 다시 객체의 상태로 복원하는 과정은 Deserialization(역직렬화) 라고 한다.

예를 들어 다음과 같은 정보를 가진다.

  • transform
  • mesh
  • material
  • member

이것들은 사람이 보기는 쉬운데, 그대로는 파일로 저장하기가 어렵다.

따라서 엔진은 이를 일정한 규칙에 따라 다른 저장 가능한 형태로 바꾸어 기록한다.

사람이 읽기 쉬운 코드를 컴파일을 통해 기계가 읽기 쉬운 오브젝트 파일로 바꾸는 것과 비슷하겠다.

1. 그래서 왜 중요한가

게임 엔진에서 직렬화는 단순 저장 기능을 넘어서 여러 시스템의 기반이 된다.

  • Scene / Level 저장 및 로드
  • Asset 저장 및 로드
  • 객체 복사 및 복제
  • Garbage Collection을 위한 참조 추적

직렬화는 객체를 파일로 저장하는 기능 이라기보다 객체 내부 상태를 엔진이 일정한 방식으로 순회하고 다룰 수 있게 하는 공통 메커니즘에 가깝다.

2. 직렬화와 복사

객체를 복사한다는 것은 결국 원본 객체가 가진 값을 읽어서 새로운 객체에 다시 써 넣는 과정이다.

예를 들어 어떤 Scene Object 를 복제한다고 하면 엔진은 다음과 같은 일을 해야 한다.

  • 원본 객체의 멤버 값을 읽고
  • 새 객체를 만들고
  • 동일한 값을 옮기며
  • 필요한 경우 참조 대상을 다시 연결한다

이 과정은 읽고 다시 쓴다는 점에서 직렬화와 매우 유사하다. 그렇기에 직렬화라는 과정이 중간에 개입하는 게 자연스럽다.

3. 직렬화와 Garbage Collection

GC는 어떤 객체가 아직 참조되고 있는지를 알아야 한다.

이를 위해 엔진은 객체 내부에서 아래 내용을 탐색한다.

  • 어떤 UObject 를 참조하는지
  • 배열 내부에 참조가 있는지
  • 연결된 서브 오브젝트가 있는지

즉 GC 역시 객체 내부 데이터를 일정한 규칙으로 방문해야 하며, 이 점에서 직렬화 시스템이 활용된다.

4. 언리얼과의 연결점

언리얼은 한마디로 말하면 FArchive 기반 직렬화를 쓴다.

언리얼의 객체 시스템은 리플렉션 기반으로 동작하며, UObject 와 UPROPERTY 는 에디터 노출, 직렬화, 참조 추적 같은 엔진 기능과 깊게 연결된다.

또한 UObject 수명 관리는 가비지 컬렉션 시스템에 의해 처리되며, ‘UPROPERTY’ 로 표시된 객체 포인터는 GC 동작에 영향을 준다.

즉 언리얼에서 직렬화는 단순히 save/load 에만 쓰이는 것이 아니라

  • 객체 상태 저장
  • 복제
  • 에디터 반영
  • 참조 추적
  • 네트워크 동기화

등과 연결되는 핵심 기반 시스템이다.