Unity编辑器中Dictionary的序列化

编辑器Dictionary序列化

开发过程中,经常需要在Unity的Inspector面板中对场景进行一些数据配置。Unity也为我们提供了许多序列化数据的方式,不过没有提供Dictionary数据的可视化序列化;今天在AssetStrore中找到一款免费的SerializableDictionary插件,非常轻巧,可是很方便,你可以根据自己的需求自定义你需要序列化的Dictionary类型,且不需要写任何写编辑器代码。当你的键值无效或者重复时,会触发警告。

AssetStore: SerializableDictionary


1

作者为我们提供了一些默认的字典类型,但是我们可以根据自己的需求,自定义一些可在Inspector面板中进行可视化操作的字典类型。

例子一

定义一个支持可视化操作的Dictionary<string,string>


在这里插入图片描述

游戏Unity中是不支持泛型数据的序列化的,所以我们序列化对象时需要制定要被序列化的对象的具体类型。

  1. 首先在UserSerializableDictionaries.cs文件中声明我们要序列化的字典类型。
[Serializable]
public class StringStringDictionary : SerializableDictionary<string, string> { }
  1. UserSerializableDictionaryPropertyDrawers.cs中定义需要可视化的字典。
[CustomPropertyDrawer(typeof(StringStringDictionary))]
public class AnySerializableDictionaryPropertyDrawer : SerializableDictionaryPropertyDrawer {}
例子二

定义一个支持可视化操作的 ***Dictionary<string,List< GameObject> >***


在这里插入图片描述

由于Unity中不支持序列化嵌套集合和嵌套数组,如果我们使用SerializableDictionary<TKey,TValue[]> 或者SerializableDictionary<TKey,List> 的方式来进行字典的可视化操作,这是不可行的,它不会在 Inspector 面板中显示且值也不会被保存。

  1. 所以,我们必须创建一个中间类,在UserSerializableDictionaries.cs文件中声明我们要存储的数据类型,将 List 或者 Array 包裹在其中,如下:
[Serializable]
public class ListGameObjectStorage : SerializableDictionary.Storage<List<GameObject>> { }
  1. 声明需要定义的字典类型(注意这里定义了第三个参数,用来指定存储的数据类型):
[Serializable]
public class StringListObjectsDictionary : SerializableDictionary<string, List<GameObject>,ListGameObjectStorage> { }
  1. UserSerializableDictionaryPropertyDrawers.cs中定义需要可视化的字典。
[CustomPropertyDrawer(typeof(ListGameObjectStorage))]
public class AnySerializableDictionaryStoragePropertyDrawer: SerializableDictionaryStoragePropertyDrawer {}
[CustomPropertyDrawer(typeof(StringListObjectsDictionary))]
public class AnySerializableDictionaryPropertyDrawer : SerializableDictionaryPropertyDrawer {}
例子三

在字典中可视化操作自定义的数据类型。

Dictionary<string,List< SkyBoxLightingPair > >


在这里插入图片描述

假如,我有一个如下的数据类型,需要使用字符串作为键值的形式将其保存在字典中,且要支持 Inspector 面板中的可视化操作。自定义数据类型如下:

[Serializable]
public class SkyBoxLightingPair
{
    public Material skyBoxmaterial;
    public string name;
    public List<string> answerList;
    public Vector3 sunEulerAngles;
    public Dictionary<string,List<GameObject>> mydict=new Dictionary<string, List<GameObject>>();
    public void Show()
    {
        Debug.Log(name);
        Debug.Log(answerList.Count);
        Debug.Log(sunEulerAngles);
    }
}
  1. UserSerializableDictionaries.cs中为自定义的数据类型定义中间类
[Serializable]
public class ListSkyBoxLightingPairStroge:SerializableDictionary.Storage<List<SkyBoxLightingPair>>{}

声明需要在字典中序列化的数据类型

[Serializable]
public class StringSkyBoxConfigPairDictonary:SerializableDictionary<string,List<SkyBoxLightingPair>,ListSkyBoxLightingPairStroge>{}
  1. 为上述定义的数据类型添加属性在 Inspector 面板中绘制的声明:
[CustomPropertyDrawer(typeof(ListSkyBoxLightingPairStroge))]
public class AnySerializableDictionaryStoragePropertyDrawer: SerializableDictionaryStoragePropertyDrawer {}
[CustomPropertyDrawer(typeof(StringSkyBoxConfigPairDictonary))]
public class AnySerializableDictionaryPropertyDrawer : SerializableDictionaryPropertyDrawer {}

以上就是在 Inspector 面板中可视化操作 Dictionary 的内容。

更多内容,欢迎访问:


在这里插入图片描述

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity ,我们可以使用 JsonUtility 类来实现对象的序列化和反序列化。对于 Dictionary 类型的对象,我们可以通过将其转换为一个包含键值对的 List 类型对象,然后对 List 类型对象进行序列化和反序列化。 下面是一个示例代码: ```csharp using System.Collections.Generic; using UnityEngine; [System.Serializable] public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver { [SerializeField] private List<TKey> keys = new List<TKey>(); [SerializeField] private List<TValue> values = new List<TValue>(); // save the dictionary to lists public void OnBeforeSerialize() { keys.Clear(); values.Clear(); foreach (KeyValuePair<TKey, TValue> pair in this) { keys.Add(pair.Key); values.Add(pair.Value); } } // load dictionary from lists public void OnAfterDeserialize() { this.Clear(); for (int i = 0; i < keys.Count; i++) { this.Add(keys[i], values[i]); } } } [System.Serializable] public class MyData { public SerializableDictionary<string, int> myDict = new SerializableDictionary<string, int>(); } public static class JsonHelper { public static string ToJson<T>(T obj) { return JsonUtility.ToJson(obj); } public static T FromJson<T>(string json) { return JsonUtility.FromJson<T>(json); } } public class Example : MonoBehaviour { private MyData data = new MyData(); private void Start() { data.myDict.Add("key1", 1); data.myDict.Add("key2", 2); string json = JsonHelper.ToJson(data); Debug.Log(json); MyData loadedData = JsonHelper.FromJson<MyData>(json); Debug.Log(loadedData.myDict["key1"]); Debug.Log(loadedData.myDict["key2"]); } } ``` 在上面的示例代码,我们定义了一个 SerializableDictionary 类来实现 Dictionary序列化和反序列化。在 MyData 类使用了 SerializableDictionary 类型的成员变量 myDict。在 JsonHelper 类,我们定义了 ToJson 和 FromJson 方法来将对象转换为 Json 字符串和从 Json 字符串加载对象。在 Example 类,我们创建了一个 MyData 对象,并向其添加了两个键值对。我们将 MyData 对象转换为 Json 字符串并输出到控制台,然后从 Json 字符串加载了一个新的对象,并输出了其的两个值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值