Unity 2017.3.1f1中如何序列化HashSet以在Inspector中使用
嘿,我刚好在Unity 2017这个版本折腾过HashSet的Inspector序列化问题,给你一套靠谱的实现方案,顺便聊聊你可能踩的坑:
正确的可序列化HashSet实现代码
核心思路和官方Dictionary的示例一致:用Unity能序列化的List作为中间载体,通过ISerializationCallbackReceiver接口在序列化/反序列化时完成HashSet和List的转换,同时自动处理List里的重复元素(毕竟HashSet本身不允许重复)。
先写一个泛型基类,封装通用的序列化逻辑:
using System.Collections.Generic; using UnityEngine; public abstract class SerializableHashSet<T> : HashSet<T>, ISerializationCallbackReceiver { // 这个List是给Unity序列化用的,会在Inspector里显示为可编辑的列表 [SerializeField] private List<T> _serializedItems = new List<T>(); // 序列化前:把HashSet里的内容同步到List public void OnBeforeSerialize() { _serializedItems.Clear(); foreach (var item in this) { _serializedItems.Add(item); } } // 反序列化后:把List的内容同步回HashSet,自动去重 public void OnAfterDeserialize() { this.Clear(); foreach (var item in _serializedItems) { if (!this.Contains(item)) { this.Add(item); } } } }
然后创建具体的可序列化HashSet子类(Unity 2017不支持直接序列化泛型类字段,所以必须针对你需要的类型写具体子类):
// 示例:可序列化的字符串HashSet [System.Serializable] public class SerializableStringHashSet : SerializableHashSet<string> { } // 示例:可序列化的整数HashSet [System.Serializable] public class SerializableIntHashSet : SerializableHashSet<int> { }
最后在你的MonoBehaviour里使用:
public class MyBehaviour : MonoBehaviour { // 这个字段会在Inspector里显示为可编辑的列表,修改后自动同步到HashSet [SerializeField] private SerializableStringHashSet _myHashSet = new SerializableStringHashSet(); void Start() { // 运行时可以正常使用HashSet的所有原生方法 Debug.Log($"HashSet元素数量:{_myHashSet.Count}"); if (_myHashSet.Contains("Test")) { Debug.Log("找到Test元素"); } } }
你可能遇到的问题排查(针对Unity 2017.3.1f1)
- 泛型类无法序列化:一定要创建具体的子类并标记
[System.Serializable],Unity老版本不支持直接把泛型类作为可序列化字段。 - Inspector看不到字段:确保你的HashSet字段是
public,或者给私有字段加上[SerializeField]标签;另外检查自定义元素类型是否加了[System.Serializable](比如你如果存自定义类,必须标记这个标签)。 - 重复元素问题:用户在Inspector的List里可能输入重复值,
OnAfterDeserialize里的去重逻辑会自动处理,保证HashSet里没有重复元素。 - 序列化回调不执行:确保你的类正确实现了
ISerializationCallbackReceiver接口,没有拼写错误;另外Unity在进入Play模式或者保存场景时才会触发序列化回调,编辑模式下实时修改List内容后,要等触发序列化才会同步到HashSet(比如切换到其他物体再切回来)。
内容的提问来源于stack exchange,提问作者Bilal Akil
相关产品推荐
相关产品推荐

