Unity Script API中有关ISerializationCallbackReceiver的问题

时间:2018-07-21 06:24:25

标签: unity3d

我正在学习有关Unity中序列化的知识,并且知道ISerializationCallbackReceiver可用于帮助序列化一些无法直接序列化的复杂数据结构。我已经在Unity 2017中测试了以下代码并发现了一些问题。

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);
    }
}

很显然,该示例向我展示了如何通过将字典更改为列表并在反序列化时恢复来序列化字典。但是,当我正常运行代码时,在检查器中发现_keys_values都为空(keys.Count = 0)。更糟糕的是,我无法在检查器中修改其值。结果,进入播放模式时什么也没出现。

所以我想知道ISerializationCallbackReceiver的实际用法是什么以及发生的原因。

1 个答案:

答案 0 :(得分:0)

每次检查器更新(基本上总是)时,都会在编辑器中调用OnBeforeSerialize,并在您的键和值列表上调用clear

我为我这样更改了此内容:

#if UNITY_EDITOR
using UnityEditor;    
#endif

public class ....{

    public void OnBeforeSerialize() {
#if UNITY_EDITOR
        if(!EditorApplication.isPlaying
        && !EditorApplication.isUpdating
        && !EditorApplication.isCompiling) return;
#endif
        ...

因此它不会在编辑时清除。