{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/unity-serialization-deserialization/",
  "atlas": "https://www.pystone.net/?node=unity-serialization-deserialization#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/unity-serialization-deserialization.md",
  "context": "https://www.pystone.net/notes/unity-serialization-deserialization.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:unity-serialization-deserialization",
  "slug": "unity-serialization-deserialization",
  "title": "序列化与反序列化",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "序列化与反序列化",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "1cfe3be54201d9d4b6795d56d6a1310fb9840f99885a03196659d98dedb12029",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "序列化与反序列化",
      "anchor": "序列化与反序列化",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#%E5%BA%8F%E5%88%97%E5%8C%96%E4%B8%8E%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96"
    },
    {
      "depth": 2,
      "text": "概念",
      "anchor": "概念",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#%E6%A6%82%E5%BF%B5"
    },
    {
      "depth": 3,
      "text": "序列化",
      "anchor": "序列化",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#%E5%BA%8F%E5%88%97%E5%8C%96"
    },
    {
      "depth": 3,
      "text": "反序列化",
      "anchor": "反序列化",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96"
    },
    {
      "depth": 2,
      "text": "作用",
      "anchor": "作用",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#%E4%BD%9C%E7%94%A8"
    },
    {
      "depth": 2,
      "text": "Unity序列化",
      "anchor": "unity序列化",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#unity%E5%BA%8F%E5%88%97%E5%8C%96"
    },
    {
      "depth": 2,
      "text": "Demo",
      "anchor": "demo",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#demo"
    },
    {
      "depth": 3,
      "text": "二进制方法（Binary Formatter）",
      "anchor": "二进制方法binary-formatter",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%96%B9%E6%B3%95binary-formatter"
    },
    {
      "depth": 3,
      "text": "Xml序列化",
      "anchor": "xml序列化",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#xml%E5%BA%8F%E5%88%97%E5%8C%96"
    },
    {
      "depth": 2,
      "text": "其他Unity数据存储方法",
      "anchor": "其他unity数据存储方法",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#%E5%85%B6%E4%BB%96unity%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E6%96%B9%E6%B3%95"
    },
    {
      "depth": 3,
      "text": "ScriptableObject(自动序列化)",
      "anchor": "scriptableobject自动序列化",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#scriptableobject%E8%87%AA%E5%8A%A8%E5%BA%8F%E5%88%97%E5%8C%96"
    },
    {
      "depth": 4,
      "text": "使用方法",
      "anchor": "使用方法",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95"
    },
    {
      "depth": 5,
      "text": "MenuItem",
      "anchor": "menuitem",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#menuitem"
    },
    {
      "depth": 5,
      "text": "CreateAssetMenu",
      "anchor": "createassetmenu",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#createassetmenu"
    },
    {
      "depth": 3,
      "text": "PlayerPrefs",
      "anchor": "playerprefs",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#playerprefs"
    },
    {
      "depth": 4,
      "text": "PlayerPrefs数据存储在哪里?",
      "anchor": "playerprefs数据存储在哪里",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#playerprefs%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E5%9C%A8%E5%93%AA%E9%87%8C"
    },
    {
      "depth": 4,
      "text": "PlayerPrefs有哪些方法？",
      "anchor": "playerprefs有哪些方法",
      "citation": "https://www.pystone.net/notes/unity-serialization-deserialization/#playerprefs%E6%9C%89%E5%93%AA%E4%BA%9B%E6%96%B9%E6%B3%95"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:game-graphics-and-runtime",
      "title": "游戏图形与运行时",
      "url": "https://www.pystone.net/notes/game-graphics-and-runtime/",
      "atlas": "https://www.pystone.net/?node=game-graphics-and-runtime#knowledge-atlas",
      "label": "游戏图形与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "Unity中的“序列化与反序列化”导航项",
      "citation": "https://www.pystone.net/notes/game-graphics-and-runtime/#unity"
    }
  ],
  "contentMarkdown": "# 序列化与反序列化\n\n> 创建时间：2020/6/9 14:33\n\nRef: <https://zhuanlan.zhihu.com/p/27990334>\n\n## 概念\n\n**序列化** 又称串行化，是.NET运行时环境用来支持用户定义类型的流化的机制。其目的是以某种存储形式使自定义对象持久化，或者将这种对象从一个地方传输到另一个地方。\n\n### 序列化\n\n序列化是指把 **对象** 转换为 **字节序列** 的过程\n\n对象序列化的最主要的用处就是在 **传递和保存对象** 的时候，保证对象的完整性和可传递性。序列化是把对象转换成有序字节流，以便在网络上传输或者保存在本地文件中。序列化后的字节流保存了 **对象的状态以及相关的描述信息** 。序列化机制的核心作用就是对象状态的保存与重建。\n\n### 反序列化\n\n反序列化是指把 **字节序列** （有序字节流）恢复为 **对象** 的过程\n\n客户端从文件中或网络上获得序列化后的对象字节流后，根据字节流中所保存的对象状态及描述信息，通过反序列化 **重建对象，恢复对象状态**\n\n## 作用\n\n  1. 永久性保存对象，保存对象的字节序列到本地文件或者数据库中；\n\n  2. 通过序列化以字节流的形式使对象在网络中进行传递和接收；\n\n  3. 通过序列化在进程间传递对象；\n\n## Unity序列化\n\nUnity的场景文件和预制体默认就是以二进制的文件保存在工程目录下。\n在 **检视面板** 中可以看到的，就是被 **成功序列化了的参数** 。与序列化相关的常用的关键字如下，可以组合使用。\n\n  * SerializeField : 表示变量可被序列化。众所周知，公有变量可以在检视面板中看到并编辑，而私有和保护变量不行。SerializeField与private，protected结合使用可以达到让脚本的变量在检视面板里可视化编辑，同时保持它的私有性的目的。\n\n  * HideInInspector : 将原本显示在检视面板上的序列化值隐藏起来。\n\n  * NonSerialized :通过此方法可以将一个公有变量不序列化并且不显示在检视面板中。\n\n  * Serializable：用在类的前面，表示该类可被序列化。\n\n**相关API**\nSerializedObject: <https://docs.unity3d.com/ScriptReference/SerializedObject.html>\nSerializedProperty: <https://docs.unity3d.com/ScriptReference/SerializedProperty.html>\n\n> 注意：并非所有的公有变量都是可以被序列化的。其中const，static是静态的，属于类而非对象，无法序列化。链表和字典在内存中的存储是不连续的，也无法序列化。其中const，static，readonly的区别可参考文章：<https://www.cnblogs.com/suizhikuo/p/4739388.html>\n\n## Demo\n\n### 二进制方法（Binary Formatter）\n\n```csharp\nclass Program\n{\n    static void Main(string[] args)\n    {\n        dynamic dyn = 1;\n        object obj = 1;\n        dyn = dyn + 3;\n        //obj = obj + 3; 报错\n\n        // Rest the mouse pointer over dyn and obj to see their\n        // types at compile time.\n        System.Console.WriteLine(dyn.GetType());\n        System.Console.WriteLine(obj.GetType());\n    }\n}\n\n```\n\n> 注意：二进制方法可以序列化私有变量，不能序列化被[NonSerialized ]修饰的变量且类需要被[Serializable ]标识。\n\n### Xml序列化\n\nXML(Extensible Markup Language, 可扩展标记语言), 标准通用标记语言(Standard Generalized Markup language, SGML)的子集。是一种用于标记电子文件使其具有结构性的标记语言。\n提供统一的方法来描述和交换独立于应用程序或供应商的 **结构化数据** 。\n\n```csharp\nclass Program\n{\n    static void Main(string[] args)\n    {\n        dynamic dyn = 1;\n        object obj = 1;\n        dyn = dyn + 3;\n        //obj = obj + 3; 报错\n\n        // Rest the mouse pointer over dyn and obj to see their\n        // types at compile time.\n        System.Console.WriteLine(dyn.GetType());\n        System.Console.WriteLine(obj.GetType());\n    }\n}\n\n```\n\n## 其他Unity数据存储方法\n\n### ScriptableObject(自动序列化)\n\n#### 使用方法\n\n##### MenuItem\n\n需要指定创建的目录和资源名称，如果资源已经存在，则不会创建新资源；\n\n```csharp\nclass Program\n{\n    static void Main(string[] args)\n    {\n        dynamic dyn = 1;\n        object obj = 1;\n        dyn = dyn + 3;\n        //obj = obj + 3; 报错\n\n        // Rest the mouse pointer over dyn and obj to see their\n        // types at compile time.\n        System.Console.WriteLine(dyn.GetType());\n        System.Console.WriteLine(obj.GetType());\n    }\n}\n\n```\n\n##### CreateAssetMenu\n\n可以在Assets下任意目录创建资源，而且可以创建多个资源；\n\n```csharp\nclass Program\n{\n    static void Main(string[] args)\n    {\n        dynamic dyn = 1;\n        object obj = 1;\n        dyn = dyn + 3;\n        //obj = obj + 3; 报错\n\n        // Rest the mouse pointer over dyn and obj to see their\n        // types at compile time.\n        System.Console.WriteLine(dyn.GetType());\n        System.Console.WriteLine(obj.GetType());\n    }\n}\n\n```\n\n在Assets下创建一个可编程对象资源，设置好所需数据；如果需要在其它脚本中获取该数据，是需要声明一个该类型变量，然后为其赋值或加载该数据资源；然后，就像使用用一个类中的公有变量一样使用即可；\n\n```csharp\nclass Program\n{\n    static void Main(string[] args)\n    {\n        dynamic dyn = 1;\n        object obj = 1;\n        dyn = dyn + 3;\n        //obj = obj + 3; 报错\n\n        // Rest the mouse pointer over dyn and obj to see their\n        // types at compile time.\n        System.Console.WriteLine(dyn.GetType());\n        System.Console.WriteLine(obj.GetType());\n    }\n}\n\n```\n\n### PlayerPrefs\n\nRef: <https://www.jianshu.com/p/579be3b8e1e3>\nPlayerPrefs是Unity内置的一个静态类，可以用于存储一些简单的数据类型：int ,string ,float。可以用它来做成计分板这类需要可持续化存储的小地方。\n\n#### PlayerPrefs数据存储在哪里?\n\n1.在Mac OS X上存储在~/Library/PlayerPrefs文件夹，名为unity.[company name].[product name].plist,这里company和product名是在project Setting中设置的\n2.在windows下，playerPrefs被存储在注册的HKCU\\Software[company name][product name]键下，这里company和product名是在project setting中设置的。\n3.在Android上，数据存储（持久化）在设备上。数据保存在SharedPreferences中。\n\n#### PlayerPrefs有哪些方法？\n\n分为五类：SetXXX , GetXXX , DeleteXXX, HasKey , Save.\n传送门：<https://docs.unity3d.com/ScriptReference/PlayerPrefs.html>\n\n  1. SetXXX : 是你要储存的数据类型，这里必须是一组键值对，第一个参数是Key,第二个参数是对应的Value。\n\n  2. GetXXX：这里是获取数据的函数，只有一个参数Key,用来获取对应Key的Value.\n3.HasKey: 这个可以用来做判断。比如有两组数据一组有XX这个Key,另一组没有XX这个Key,这个时候我们就可以对这两组数据进行差异化操作。\n\n  3. DeleteXX:用于删除数据。\n\n  4. Save:用于在突发退出程序时，保存数据以备恢复时使用，但是会导致程序间断所以不建议调用。\n"
}
