序列化和反序列化 —— unity篇

一、什么是序列化和反序列化

  1. 序列化是指把对象转换为字节序列的过程,而反序列化是指把字节序列恢复为对象的过程;.
  2. 序列化:对象序列化的最主要的用处就是在传递和保存对象的时候,保证对象的完整性和可传递性。序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。序列化后的字节流保存了对象的状态以及相关的描述信息。序列化机制的核心作用就是对象状态的保存与重建。
  3. 反序列化:客户端从文件中或网络上获得序列化后的对象字节流后,根据字节流中所保存的对象状态及描述信息,通过反序列化重建对象
  4. 本质上讲,序列化就是把实体对象状态按照一定的格式写入到有序字节流,反序列化就是从有序字节流重建对象,恢复对象状态。


二、为什么需要序列化与反序列化


        我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等, 而这些数据都会以二进制序列的形式在网络上传送。
        那么当两个进程进行通信时,能否实现进程间的对象传送呢?答案是可以的!如何做到呢?这就需要序列化与反序列化了!
        换句话说,一方面,发送方需要把这个对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出对象。
        当我们明晰了为什么需要Java序列化和反序列化后,我们很自然地会想序列化的好处。其好处一是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),二是,利用序列化实现远程通信,即在网络上传送对象的字节序列。

三、序列化和反序列化的意义

  1. 永久性保存对象,保存对象的字节序列到本地文件或者数据库中;
  2. 通过序列化以字节流的形式使对象在网络中进行传递和接收;
  3. 通过序列化在进程间传递对象;

四、举例

// 需要导入命名空间
using System.IO;
using System.Xml.Serialization;
using UnityEditor;

// 先定义一个类:
public class Studnet{
    public string m_Name = "仑仑";
}

public class SerializeDemo : MonoBehaviour {


    void Start()
    {
        // 序列化:
        Student student = new Student();
        // 第一要确定储存的位置
        // Application.dataPath就是unity中的Asset文件夹 
        StreamWriter sw = new StreamWriter(Application.dataPath + "/Demo.xml");
        // 第二要对什么类型序列化
        XmlSerializer xs = new XmlSerializer(typeof(Student));
        // 第三对对象序列化
        xs.Serialize(sw, student);
        // 关闭流
        sw.Close();
        // 刷新Asset文件
        AssetDatabase.Refresh();
        // 运行程序会在Asset目录下看到Demo.xml文件


        // 反序列化
        // 第一确定对哪个文件进行反序列化
        StreamReader sr = new StreamReader(Application.dataPath + "/Demo.xml");
        // 第二要确定对什么类型反序列化
        XmlSerializer xs1 = new XmlSerializer(typeof(Student));
        // 第三反序列化
        Student student1 = xs1.Deserialize(sr) as Student;
        // 关闭流
        sr.Close();
        // 会在控制台看到 “仑仑”
        print(student1.m_Name);
    }
}

五、Unity中的序列化和反序列化

序列化规则

Unity 中的序列化程序在实时游戏环境中运行。这对性能有很大影响。因此,Unity 中的序列化与其他编程环境中的序列化行为不同。以下部分概述了如何在 Unity 中使用序列化。要使用字段序列化,您必须确保它:

  • 是 public,或具有 SerializeField 属性
  • 不是 static
  • 不是 const
  • 不是 readonly
  • 有一个fieldtype可以序列化的。

可以序列化的简单字段类型

  • Serializable 具有属性的自定义非抽象、非泛型类
  • Serializable 具有属性的自定义结构
  • 对派生自 UnityEngine.Object的对象的引用
  • 原始数据类型(intfloatdoubleboolstring, 等)
  • 枚举类型
  • 某些 Unity 内置类型:Vector2Vector3Vector4RectQuaternionMatrix4x4ColorColor32LayerMaskAnimationCurveGradientRectOffset,GUIStyle

可序列化的容器字段类型

  • 可以序列化的简单字段类型的数组
  • 一个List<T>可以序列化的简单字段类型

注意:Unity 不支持多级类型(多维数组、交错数组和嵌套容器类型)的序列化。如果你想序列化这些,你有两个选择:将嵌套类型包装在一个类或结构中,或者使用序列化回调ISerializationCallbackReceiver 来执行自定义序列化。有关详细信息,请参阅有关 自定义序列化 的文档。

Unity实践

Unity序列化的关键字是 Serializable 和 SerializeField.

  • Serializable: 用于 自定义的,非 abstract 的类. 结构体等 , 使这类型也能序列化
  • SerializeField: 用于 非public 类型(如private),  使非public 类型也能序列化

====>

Dictionary容器序列化


在实践中,Dictionary容器也是经常使用的容器类。系统不支持Dictionary容器的序列化给我们造成了不便,我们也可以通过自定义序列化 / Odin 来解决 。

Odin 插件

Odin Inspector and Serializer | Improve your workflow in Unityhttps://odininspector.com

 配合 [ShowInInspector] 使用 

点击跳转 Odin下载

猜你喜欢

转载自blog.csdn.net/DeveloperZZW/article/details/122574649
今日推荐