EveryDay.DevUp

[Unity] Serialize (직렬화) - Serialize Dictionary 본문

Unity

[Unity] Serialize (직렬화) - Serialize Dictionary

EveryDay.DevUp 2020. 6. 26. 00:55

▶ 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

 

스크립트 직렬화 - Unity 매뉴얼

직렬화는 데이터 구조나 오브젝트 상태를 Unity 에디터가 저장하고 나중에 재구성할 수 있는 포맷으로 자동으로 변환하는 프로세스를 말합니다. Unity 에디터에서는 저장 및 로딩, 인스펙터 창, 인

docs.unity3d.com