什么是序列化和反序列化:序列化和反序列化主要用来解决对象的传输问题。其中序列化用来将对象转换成二进制流;反序列化用来将二进制流转换成对象。
Unity序列化:Unity序列化器的实现十分简单,目的是为了非常快速的进行序列化和反序列化操作。具有以下特性:
1.可以被序列化的类型如下所示:
1.1.某些Unity内置类型。如:Vector2、Vector3、Vector4、Rect、Quaternion、Matrix4x4、Color、Color32、LayerMask、AnimationCurve、Gradient、RectOffset、GUIStyle、UnityEvent。
1.2.某些C#基元类型。如:sbyte、byte、short、ushort、int、uint、long、ulong、float、double、char、string、bool。
1.3.某些基础枚举类型。在Unity5.6之前,只支持byte和int枚举类型。在Unity5.6之后,只支持sbyte、byte、short、ushort、int、uint枚举类型。
1.4.使用SerializableAttribute定制特性应用的自定义结构体类型。
1.5.继承自UnityEngine.Object的自定义引用类型。
1.6.使用SerializableAttribute定制特性应用的自定义引用类型,并且该自定义引用类型不能使用static、abstract修饰符。
1.7.某些容器类型。如:上述类型的一维数组、List类型。
2.当自定义结构体类型或者自定义引用类型实现了ISerializationCallbackReceiver接口的时,就可以在OnBeforeSerialize函数里面实现序列化之前的操作以及在OnAfterDeserialize函数里面实现反序列化之后的操作。
3.可以使用JsonUtility的ToJson函数来将可序列化类型的实例进行序列化成json格式串,也可以使用JsonUtility的FromJson或者FromJsonOverwrite函数来将json格式串反序列化成可序列化类型的实例。
4.类型中可以被序列化的成员只有字段。具有以下特性:
4.1.可以使用NonSerializedAttribute定制特性来让字段不能被序例化。
4.2.要想字段被成功的序列化,那么首先该字段就不能应用NonSerializedAttribute定制特性。接着该字段所对应的类型必须是可以序列化的类型。然后该字段不能使用static、const、readonly修饰符。最后该字段必须使用public访问权限或者SerializeFieldAttribute定制特性。
4.3.检视面板上会显示序列化成功的字段。
4.4.可以使用HideInInspectorAttribute定制特性来让序列化成功的字段在检视面板上面隐藏起来。
4.5.Unity序列化器不支持序列化多态情况。当字段接收子类实例赋值时,如果该字段可以被成功的序列化,那么该字段也就只能序列化基类部分。
4.6.Unity序列化器不支持序列化空引用数值情况。当字段在进行序列化时,如果该字段对应类型里面存在空引用数值,那么Unity序列化器首先就会通过该空引用数值对应类型的构造函数来创建一个实例;然后通过该实例来替换该空引用数值。
参考代码如下所示:
[Serializable]
public class NodeA
{
public NodeB nodeB = null;
}
[Serializable]
public class NodeB
{
public int value = 10;
}
public class MTest : MonoBehaviour
{
public NodeA nodeA;
}
空引用数值被具体实例替换的效果如下图所示:

4.7.Unity序列化器不支持序列化循环引用情况。当字段对应的类型存在循环引用自身类型时,为了避免无线循环下去,Unity就会限制最大循环深度为10。在达到这个最大循环深度之前,Unity会出现严重的卡顿。
参考代码如下所示:

本文深入探讨Unity中的序列化机制,包括Unity内置序列化器的功能、限制及使用技巧,Odin序列化器如何扩展Unity序列化能力,以及序列化调试器的使用方法。
:序列化调试器详解&spm=1001.2101.3001.5002&articleId=123770865&d=1&t=3&u=b492bc90854540688c0bcb07b93515a6)
1108

被折叠的 条评论
为什么被折叠?



