序列化是指把对象转换为字节序列的过程,而反序列化是指把字节序列恢复为对象的过程。序列化最主要的用途就是传递对象和保存对象。
在Unity中保存和加载、prefab、scene、Inspector窗口、实例化预制体等都使用了序列化与反序列化。
1> 自定义的具有Serializable特性的非抽象、非泛型类(所有继承UnityEngine.Object的类都具有Serializable特性,如MonoBehaviour)
2> 自定义的具有Serializable特性的结构体(Unity内置结构体类型都都具有Serializable特性)
3> 可序列化类型的数组和列表(如int、string列表),栈、队列、字典等都不能被序列化
4> 枚举类型
最直观的就是在Unity中的检视面板可以看到字段就是被成功序列化了的参数,与序列化相关的常用关键字有SerializeField,HideInInspector,NonSerialized,Serializable :
1> SerializeField : 表示变量可被序列化,SerializeField与private,protected结合使用可以达到让脚本的变量在检视面板里可视化编辑,同时保持它的私有性的目的
2> HideInInspector : 将原本显示在检视面板上的序列化值隐藏起来
3> NonSerialized :将一个公有变量不序列化并且不显示在检视面板中
4> Serializable:用在类的前面,表示该类可被序列化,Serializable不会被派生类所继承,每个类想要被序列化需要单独加Serializable特性
使用二进制序列化时,每个类都需要Serializable标识
只有通过二进制进行序列化和反序列化时才能调用到OnSerializing、OnSerialized、OnDeserializing、OnDeserialized这四个特性
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
using System.IO;
using System;
using System.Runtime.Serialization.Formatters.Binary;
public class Test : MonoBehaviour
{
/// <summary>
/// 序列化二进制
/// </summary>
public static bool BinarySerialize(string outputPath, object obj)
{
if (!IOUtils.IsFile(outputPath))
{
Debug.LogError($"序列化二进制失败,输出路径有误,filePath:{
outputPath}");
return false;
}
try
{
string dirPath = Path.GetDirectoryName(outputPath);
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
using (FileStream fs = new FileStream(outputPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(fs, obj);
}
}
catch (Exception e)
{
Debug.LogError($"序列化二进制失败,{
e}");
return false;
}
return true;
}
/// <summary>
/// 反序列化二进制
/// </summary>
public static T BinaryDeserialize<T>(string binaryFilePath)
{
if (!File.Exists(binaryFilePath))
{
Debug.LogError($"反序列化二进制失败,找不到二进制文件:{
binaryFilePath}");
return default;
}
T obj = default;
try
{
using (FileStream fs = File.OpenRead(binaryFilePath))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
obj = (T)binaryFormatter.Deserialize(fs);
}
}
catch (Exception e)
{
Debug.LogError($"反序列化二进制失败,{
e}");
return obj;
}
return obj;
}
}
使用Json序列化时,第一层类不需要Serializable标识,其他类都需要Serializable标识
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
using System.IO;
using System;
public class Test : MonoBehaviour
{
[MenuItem("Tools/JsonSerialize")]
private static void JsonSerialize()
{
People p = new People();
Name name = new Name();
name.name1 = "l";
name.name2 = "hw";
p.name = name;
p.age = 26;
string jsonString = JsonUtility.ToJson(p);
string path = Application.