转子阏乐
转子7dot9 Laputa
当你在inspector操作数据的时候,unity就会把这些数据序列化为文件,当游戏在运行的时候,unity就会反序列化这些文件来赋值给运行的对象。
在继承了MonoBehaviour的游戏对象通过克隆instantiate方法的时候,它也会序列化和反序列化。
Serializable
用于自定义的,非abstract的类,结构体等SerializeField
用于非public类型,使非public类型也能序列化FormerlySerializedAs
当你修改一个原先已经存在的变量名时,例如public GameObject player;
之后你想要修改player变量名,而如果此时你直接修改,那么之前你再inspector中引用的对象将丢失,你需要全部重新关联一次。
[FormerlySerializedAs("player")] public GameObject playerFemale;
准备序列化的对象必须设置[System.Serializable]标签,指示一个类可以序列化。
序列化
对象是暂时保存在内存中的,有时为了使用介质转移对象,并且把对象的状态保持下来,就需要把对象保存下来。
[Serializable]
public class MyObject{}
MyObject obj = new MyObject();
IFormatter formatter = new BinaryFormatter()
Stream stream = new FileStream("MyFile.bin",FileMode.Create,FileAccess.Write,FileShare.None);
formatter.Serialize(stream,obj);
stream.Close()
反序列化
把介质中的东西还原成对象。
对对象进行反序列化时并不会调用构造函数
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin",FileMode.Open,FileAccess.Read,FileShare.Read);
MyObject obj = (MyObject)formatter.Deserialize(fromStream);
fromStream.Close();
选择序列化
[NonSerialized]
public int n2;
自动序列化
[serializable]
public class MyObject : ISerializable{
public int n1;
public MyObject(SerializationInfo info,StreamContext context){
n1 = info.GetInt32("i");
}
public virtual void GetObjectData(SerializationInfo info,StreamingContext context){
info.AddValue("i",n1);
}
}
序列化条件
需同时满足
1. public类型 或者有[serializaField]
2. 不是static
3. 不是const
4. 不是readonly
5. 类型必须是Unity可以序列化的类型
Unity可以序列化类型
1. 自定义的,非abstract的类,且有[serializable]
2. 有[serializable]的结构体
3. UnityEngine.Object的子类的引用
4. 原生类型
5. 以上类型的数组
6. 以上类型的List<T>
注意
- 序列化系统对多态支持不好。如果有一个数组,比如是动物数组,其中存放了三个继承自动物类的子类的实例,如兔子、狗、猫,那么实例化后数组中将保存的是三个动物的实例。
- 不能序列化有null的变量,序列化时将会new出一个实例出来,而new出的实例中又需要new出一个实例,这样便进入一个死循环。
- 序列化不在主线程中运行
ISerializationCallbackReceiver
- OnBeforeSerialize()序列化之前
- OnAfterDeserialize()反序列化之后