有时我们使用的类型Unity并不能自动将其序列化(比如抽象类型数组)
虽然能通过实现IAutoSerialization将其序列化 但是每次书写较为麻烦
所以写了一个接口方便完成上述内容
代码在Unity 2021.2.14f1c1测试通过
实现接口 只需要实现Data属性 Data属性包装了一个Unity可以序列化的Byte数组
例如:
class Test : MonoBehaviour, IAutoSerialization
{
// 需要实现的接口
Data{get => data; set => data = value;}
// 一个Unity可以自动序列化的Byte[]类型
[SerializeField]
[HideInInspector]
private byte[] data;
// 一个Unity无法自动序列化的类型 而且你需要将其序列化 使用CustomSerialization特性标记它
[CustomSerialization]
private AbsClass[] array;
}
代码
通过接口的默认实现 来实现将带有CustomSerialization特性的字段自动序列化与反序列化
代码会在GitGist更新CSDN代码可能会过期:
IAutoSerialization.cs
[System.AttributeUsage(System.AttributeTargets.Field)]
public class CustomSerialization : System.Attribute { }
public interface IAutoSerialization : ISerializationCallbackReceiver
{
private static Dictionary fieldDict;
static IAutoSerialization()
{
fieldDict = new Dictionary();
}
private FieldInfo[] GetInfoData(Type type)
{
if (!fieldDict.ContainsKey(type))
{
var infos = GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).
Where(f => f.GetCustomAttribute() != null).ToArray();
fieldDict.Add(type, infos);
}
return fieldDict[type];
}
byte[] Datas { get; set; }
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
var fieldInfos = GetInfoData(GetType());
// 暂存所有数据
var databuffer = new object[fieldInfos.Length];
for (int i = 0; i < fieldInfos.Length; i++)
{
databuffer[i] = fieldInfos[i].GetValue(this);
}
// 序列化暂存数组
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
formatter.Serialize(ms, databuffer);
Datas = ms.ToArray();
ms.Close();
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
var fieldInfos = GetInfoData(GetType());
BinaryFormatter formatter = new BinaryFormatter();
object[] databuffer = null;
using (MemoryStream ms = new MemoryStream(Datas))
{
try
{
databuffer = formatter.Deserialize(ms) as object[];
}
catch (Exception)
{
Debug.LogWarning($"{GetType()}数据反序列化失败 数据丢失", this as UnityEngine.Object);
Datas = null;
}
ms.Close();
}
if (databuffer == null) return;
// 反序列化所有数据
for (int i = 0; i < databuffer.Length; i++)
{
if (databuffer[i] == null) continue;
fieldInfos[i].SetValue(this, databuffer[i]);
}
}
}


![[Unity.序列化]通过接口的默认实现自动序列化与反序列化Unity中的字段 [Unity.序列化]通过接口的默认实现自动序列化与反序列化Unity中的字段](http://www.mshxw.com/aiimages/31/901698.png)
