ISerializationCallbackReceiver 시리얼라이즈 콜백 활용하기

유니티 매뉴얼 : ISerializationCallbackReceiver
https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html

 

#. Serialize가 불가능한 Dictionary

유니티에서 Dictionary는 Serialize가 가능한 형식이 아니다.

그럼에도 불구하고 시리얼라이즈를 시도하려면 편법을 사용해야하는데,

 

그 방법 중 하나가 ISerializationCallbackReceiver 인터페이스 활용하는 것.

아래는 유니티 매뉴얼에 있는 예제이다.

 

Serialize시에는

ISerializationCallbackReceiver.OnBeforeSerialize() 로

Dictionary -> key List, value List 두 개로 변환하여 Serialize 한다.

 

Deserialize시에는

ISerializationCallbackReceiver.OnAfterDeserialize() 로

Key List, value List -> Dictionary로 다시 담는다.

using UnityEngine;
using System;
using System.Collections.Generic;

public class SerializationCallbackScript : MonoBehaviour, ISerializationCallbackReceiver
{
    public List<int> _keys = new List<int> { 3, 4, 5 };
    public List<string> _values = new List<string> { "I", "Love", "Unity" };

    //Unity doesn't know how to serialize a Dictionary
    public Dictionary<int, string>  _myDictionary = new Dictionary<int, string>();

    public void OnBeforeSerialize()
    {
        _keys.Clear();
        _values.Clear();

        foreach (var kvp in _myDictionary)
        {
            _keys.Add(kvp.Key);
            _values.Add(kvp.Value);
        }
    }

    public void OnAfterDeserialize()
    {
        _myDictionary = new Dictionary<int, string>();

        for (int i = 0; i != Math.Min(_keys.Count, _values.Count); i++)
            _myDictionary.Add(_keys[i], _values[i]);
    }

    void OnGUI()
    {
        foreach (var kvp in _myDictionary)
            GUILayout.Label("Key: " + kvp.Key + " value: " + kvp.Value);
    }
}

 

 

#. 또 다른 활용방법

이것이 기본적인 예제이며,

Serialize와 관련된 처리가 아닌 부분으로도 활용할 수 있다.

 

예를 들어 아래와 같이 serialize Sprite의 처리를 넣어주면

스크립트에 할당된 스프라이트가 오브젝트의 이름이 알맞게 자동으로 바뀌게 된다.

using UnityEngine;

public class SerializeTest : MonoBehaviour, ISerializationCallbackReceiver
{
    [SerializeField] Sprite portrait;

    public void OnBeforeSerialize()
    {
        if(portrait != null)
        {
            GetComponent<SpriteRenderer>().sprite = portrait;
            gameObject.name = portrait.name + "_Image";
        }
    }

    public void OnAfterDeserialize()
    {
    }
}

 

스프라이트를 바꿀때마다 오브젝트의 이름이 바뀌는 모습

 

에디터에서 동작하는 콜백들은 너무 남용하면 오류와 렉을 유발할 수 있지만

잘 활용해보면 반복작업을 하는 경우에 어느정도 활용될만한 여지가 있어 보있다.

 

 

 

 

댓글

Designed by JB FACTORY