unity序列化

2021年11月24日 阅读数:4
这篇文章主要向大家介绍unity序列化,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

###什么是序列化node

  • unity的序列化在unity的开发中起着举重足轻的地位,许多核心的功能都是基于序列化和反序列化来实现的。序列化简单来说就是就是将咱们所要保存的数据进行二进制存储,而后当咱们须要的时候,在读取二进制文件,反序列化回来。下面是一些经常使用的序列化的例子:c#

    • 存储脚本化的数据。在咱们的c#代码中,能够将咱们所要存储的数据进行序列化,进行存储
    • prefab与初始化。在unity开发过程当中咱们会制做不少的预制体(prefab),这些prefab都是序列化,以二进制的形式保存的。当你要对预制体进行初始化的时候,unity根据以前序列化的信息新建出一个物体,而后将物体上的信息反序列化回去,实现相似于clone的效果。
    • 在unity编辑器的拓展功能,AssetBundle等等,均可以看到序列化的身影。
  • 可序列化对象数组

    • 公有的,或者有[SerializeField]属性,非静态,很是量,非只读
    • 自定义非抽象类,而且有Serializable属性
    • 继承自unity.object的类
    • 数组和List

    注意:数据结构

    • 字典不能经过添加Serializable属性进行序列化
    • 若是一个类基类不能被序列化,那它即使添加了序列化特性也没法被序列化
    • 序列化不能保存另外一个要反序列化的对象指针,由于反序列化是new一个新的对象,指针指向的内存将不会是原对象
  • 可采用unity编辑器的序列化类ScriptableObject,当咱们继承这个基类,咱们就能够调用unity给咱们的接口进行序列化了。具体的序列化接口能够到unity的官方接口文档上查看使用方法,这里不具体介绍。编辑器

  • 下面来说讲具体开发过程当中我的遇到的坑指针

    • 首先给出一段开发过程当中的报错信息
    Serialization depth limit 7 exceeded at 'XNodeScripts::ConfigNode.nodeList'. There may be an object composition cycle in one or more of your serialized classes.
    
    Serialization hierarchy:
    8: XNodeScripts::ConfigNode.nodeList
    7: XNodeScripts::ConfigNode.nodeList
    6: XNodeScripts::ConfigNode.nodeList
    5: XNodeScripts::ConfigNode.nodeList
    4: XNodeScripts::ConfigNode.nodeList
    3: XNodeScripts::ConfigNode.nodeList
    2: XNodeScripts::ConfigNode.nodeList
    1: XNodeScripts::ConfigNode.nodeList
    0: XNodeScripts::SelectMsgNode.rootNode
    

    这里的报错信息提示咱们我在建立序列化数据nodeList的时候,多是在这个nodeList里面有循环的序列化。这边咱们发现unity还提示咱们序列化的深度为7。我在网上查到,原来咱们的子系统是构建在序列化系统之上的,因此若是听任其死循环的序列化的话,当一个很是大的序列化流将致使整个系统崩溃。为了不这样的状况,unity采用了一个深度为7的阙值,及循环序列化为空的子集最多只能为7个。咱们在进行序列化的建立的时候,一个很是常见的错误就是经过序列化构造一个相似树状结构的数据结构,在咱们声明的序列化类里面,若是还有包含自己的对象,相似于code

    [Serializable]
    public class DepthClass : ScriptableObject
    {
        public List<DepthClass> depthObjects; 
    }
    

    上诉的这种序列化结构,就会产生我以前所示的系统报错。**有效的避免空值的序列化,**对于树状结构包括字典的存储,我采用的是List<string> key的存储方式,对下一个子节点,都用字符串做为一个key值来存储,而后将全部的节点都存储在一个List中。这样咱们经过key来寻找节点,其中咱们能够采用堆存储或者更加高效的查询方式,来避免效率的底下。目前尚未想到更好的解决方法。。。23333对象