使用ISerializationCallbackReceiver解决HashSet/Dictionary无法序列化的问题
Posted thpgames
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用ISerializationCallbackReceiver解决HashSet/Dictionary无法序列化的问题相关的知识,希望对你有一定的参考价值。
自定义数据类被标记为[Serializable]后, 像 HashSet<T> / Dictionary<T> 类型的数据依然无法被Unity自动序列化。一种办法是内部再存一个数据列表(一般是List<T>类型),序列化之前先把数据倒腾到List<T>中, 在运行时加载后再执行自己写的 "Init()" 之类的函数将数据从List<T>中倒腾到 HashSet<T>中。实际上,对于这种情况,Unity已经提供了一个处理方式: ISerializationCallbackReceiver。自定义的数据类只需要实现这个接口,Unity自己就会在序列化/发序列化时自动执行对应操作。
该接口很简单,在Unity中定义如下:
[RequiredByNativeCode] public interface ISerializationCallbackReceiver { // // 摘要: // Implement this method to receive a callback after Unity deserializes your object. //将在Unity反序列化你的对象后被执行。 [RequiredByNativeCode] void OnAfterDeserialize(); // // 摘要: // Implement this method to receive a callback before Unity serializes your object. //将在Unity序列化你的对象之前被执行。 [RequiredByNativeCode] void OnBeforeSerialize(); }
当然,并非只有集合类才能这样操作。以下是一段简单的示例代码:
1 using System.Collections.Generic; 2 using UnityEngine; 3 using System; 4 5 namespace THP.ExampleCode.SerializationCallback 6 { 7 [Serializable] 9 public class Items : ISerializationCallbackReceiver 10 { 11 /// <summary> 12 /// dictionary of items. key: Item.Id value: Item 13 /// </summary> 14 public Dictionary<int, Item> ItemDict = new Dictionary<int, Item>(); 15 [SerializeField] 16 List<Item> itemList; 17 18 public void OnAfterDeserialize() 19 { 20 foreach (var item in itemList) 21 { 22 ItemDict.Add(item.Id, item); 23 } 24 } 25 26 /// <summary> 27 /// 将在序列化之前执行。 28 /// </summary> 29 public void OnBeforeSerialize() 30 { 31 itemList = new List<Item>(); 32 foreach (var kv in ItemDict) 33 { 34 itemList.Add(kv.Value); 35 } 36 } 37 } 38 39 [Serializable] 40 public class Item : ISerializationCallbackReceiver 41 { 42 [NonSerialized] 43 public int Id; 44 [NonSerialized] 45 public string Name; 46 // ... other infos 47 [SerializeField] 48 private byte[] compressedByteArray; 49 50 public void OnAfterDeserialize() 51 { 52 CompressToolAtSomewhere.DecompressItemInfo(compressedByteArray, this); 53 } 54 55 public void OnBeforeSerialize() 56 { 57 compressedByteArray = CompressToolAtSomewhere.CompressItemInfo(this); 58 } 59 } 60 }
以上是关于使用ISerializationCallbackReceiver解决HashSet/Dictionary无法序列化的问题的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)