Unity-序列化和反序列化

序列化是指把对象转换为字节序列的过程,而反序列化是指把字节序列恢复为对象的过程。序列化最主要的用途就是传递对象和保存对象。
在Unity中保存和加载、prefab、scene、Inspector窗口、实例化预制体等都使用了序列化与反序列化。

1 可序列化类型

1> 自定义的具有Serializable特性的非抽象、非泛型类(所有继承UnityEngine.Object的类都具有Serializable特性,如MonoBehaviour)
2> 自定义的具有Serializable特性的结构体(Unity内置结构体类型都都具有Serializable特性)
3> 可序列化类型的数组和列表(如int、string列表),栈、队列、字典等都不能被序列化
4> 枚举类型

2 Unity中的序列化和反序列化

最直观的就是在Unity中的检视面板可以看到字段就是被成功序列化了的参数,与序列化相关的常用关键字有SerializeField,HideInInspector,NonSerialized,Serializable :
1> SerializeField : 表示变量可被序列化,SerializeField与private,protected结合使用可以达到让脚本的变量在检视面板里可视化编辑,同时保持它的私有性的目的
2> HideInInspector : 将原本显示在检视面板上的序列化值隐藏起来
3> NonSerialized :将一个公有变量不序列化并且不显示在检视面板中
4> Serializable:用在类的前面,表示该类可被序列化,Serializable不会被派生类所继承,每个类想要被序列化需要单独加Serializable特性

3 通过二进制序列化与反序列化

使用二进制序列化时,每个类都需要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
{
   
    /// 
    /// 序列化二进制
    /// 
    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;
    }

 
    /// 
    /// 反序列化二进制
    /// 
    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;
    }
}

4 通过Json序列化与反序列化

使用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.

你可能感兴趣的:(Unity,游戏开发,C#,unity,lucene,游戏引擎)