[Unity] Serialize (직렬화) - Serialize Dictionary
▶ Serialize ( 직렬화 )
: Unity에서 사용하는 데이터나 GameObject의 정보를 저장하고 불러오기 위해 사용하는 포맷으로 자동으로 변환하는 프로세스이다.
: Unity Editor에서 인스펙터 창의 정보나 프리팹의 정보를 저장하고 불러오는데 사용되고 있다.
▶ hot reloading ( 핫 리로드 )
: Unity Editor에서 Serialize 되는 데이터 또는 코드의 수정이 발생한 경우 실시간으로 변경 사항을 체크하여 데이터를 직렬화 한다. 이때 직렬화가 적용되지 않는 정보는 데이터를 잃게 된다.
▶ Serialize Rules ( 자동으로 직렬화가 되는 규칙 )
: Class안에 public으로 선언되거나 [SerializeField] 속성이 정의 되어 있는 경우 직렬화가 가능한 필드 타입에 한하여 자동으로 직렬화가 된다.
※ 직렬화가 가능한 필드 타입
① [Serializable] 속성이 정의된 비추상, 비정적 클래스
[Serializable]
public class UIReferenceData
{
public string path;
}
② [Serializable] 속성이 정의된 구조체
[Serializable]
public struct structData
{
public string path;
}
③ UnityEngine.Object를 상속받는 클래스 ( GameObject, Texture2D, AnimationClip ... )
④ 기본 데이터 형식 ( int, float, double, bool, string, Vector2, Vector3, Vector4, Rect, Quaternion, Matrix4x4, Color, Color32, LayerMask, AnimationCurve, Gradient, RectOffset, GUIStyle )
⑤ 직렬화 할 수 있는 단순 필드 타입의 배열 또는 List
: static, const, readonly, get, set 의 경위 위의 조건을 만족한다 해도 직렬화가 되지 않는다.
▶ 직렬화가 자동으로 되지 않는 데이터의 경우, 직렬화를 어떻게 할 수 있는가?
: ISerializationCallbackReceiver interface를 상속 받아서 직렬화가 가능한 필드 타입으로 수정하여 사용할 수 있다.
: 가령 Dictionary의 경우 Unity에서 직렬화를 지원하지 않기 때문에 일반적으로는 데이터를 저장하고 불러오는데 사용할 수 없다. 하지만 ISerializationCallbackReceiver 를 통해 개발자가 직렬화가 가능한 Dictionary를 만들 수 있다.
using System.Collections.Generic;
using UnityEngine;
using System;
[Serializable]
public class SerializeDictionary<K, V> : Dictionary<K,V>, ISerializationCallbackReceiver
{
[SerializeField]
List<K> keys = new List<K>();
[SerializeField]
List<V> values = new List<V>();
public void OnBeforeSerialize()
{
keys.Clear();
values.Clear();
foreach( KeyValuePair<K, V> pair in this )
{
keys.Add( pair.Key );
values.Add( pair.Value );
}
}
public void OnAfterDeserialize()
{
this.Clear();
for( int i = 0, icount = keys.Count; i < icount; ++i )
{
this.Add( keys[i], values[i] );
}
}
}
: generic으로 타입을 미리 정의 하지 않았기 때문에 기존 dictionary처럼 바로 사용할 수는 없다. 별도의 상속 받는 클래스에서 타입을 정의한 후 사용할 수 있다.
[Serializable]
public class SerializeDicString : SerializeDictionary<string, string> { }
public SerializeDicString dicString = new SerializeDicString();
: ISerializationCallbackReceiver에서 OnBeforeSerialize는 데이터를 저장할 때, OnAfterDeserialize는 데이터를 불러올 때 사용된다.
참고 자료 : docs.unity3d.com/kr/2018.4/Manual/script-Serialization.html