Unity教程之-unity3d中的JSON序列化传输数据

 

JSON 序列化功能和从 JSON 格式 转换到 对象。与 web 服务交互,或只是为了打包和拆包数据 到一个基于文本的格式很容易,这可以非常有用。

使用简单
JSON 序列化功能是围绕一个‘structured’的 JSON,意味着你描述变量将要存储在您的 JSON 数据中通过创建一个类或结构的概念。例如:

[Serializable] public class MyClass
{
public int level;
public float timeElapsed;
public string playerName;
}

这定义普通 C# 类包含三个变量-level, timeElapsed, and playerName -并将其标记为可序列化,这是它工作于 JSON 序列化程序的必要条件。然后可以创建它的这样一个实例:

MyClass myObject = new MyClass();
myObject.level = 1;
myObject.timeElapsed = 47.5f;
myObject.playerName = “Dr Charles Francis”;

通过使用 JsonUtility.ToJson。并将其序列化为 JSON 格式:

string json = JsonUtility.ToJson(myObject);

若要将 JSON 转换回对象,请使用 JsonUtility.FromJson:

myObject = JsonUtility.FromJson<MyClass>(json);

这将创建一个新的 MyClass 实例并使用 JSON 数据设置值。如果 JSON 数据包含不映射到 MyClass 中的字段的值将会简单地忽略这些值,和如果 JSON 数据缺少 MyClass 中的字段的值,然后才会剩下这些字段,在其构造中返回的对象值。

JSON 序列化 程序目前不支持非结构化’ JSON 相工作 (即导航和编辑 JSON 作为任意目录树的键-值对)。如果你需要这样做,你应该寻找一个更齐全的 JSON 库。

用 JSON 覆盖对象

它也是可能采取的 JSON 数据和反序列化 ‘在’ 已经创建的对象,覆盖已存在的数据:

JsonUtility.FromJsonOverwrite(json, myObject);

将剩下的 JSON 不包含一个值对象上的任何字段不变。此方法允许你通过故意用只包含一个小的字段子集的 JSON 覆盖他们通过重用您先前创建的对象,也 ‘补丁’ 对象保持分配到最低限度。

请注意,JSON 序列化程序 API 支持 MonoBehaviour 和 ScriptableObject 的子类,以及普通的结构类。但是,当反 JSON 序列化到 MonoBehaviour 或 ScriptableObject 的子类,则必须使用 FromJsonOverwrite;  FromJson 不支持,并将引发异常。

受支持的类型

API 支持任何 MonoBehaviour 子类、 ScriptableObject-子类或 使用[可序列化] 属性的普通类/结构 。你装换的对象,是Unity 标准序列化程序进行处理,所以相同的规则和限制适用,也在检查器中;只有字段进行序列化,并像字典类型不受支持。

目前不支持的 API,例如primitive 类型或数组,传递其他类型。现在你将需要包装类在类或结构的某种排序形式。

在编辑器中,还有一个平行的 API-EditorJsonUtility-允许您将任何 UnityEngine.Object 派生的类型进行 JSON 序列化。这会产生包含相同的数据,YAML 表示的对象的 JSON。
性能

测试显示 JsonUtility 是显著快于.NET JSON 的一般解决方法 (尽管某些的功能 较少)。

GC 内存使用是在最低限度:
• ToJson() 只为返回的字符串分配 GC 内存。
• FromJson() 分配 GC 内存仅为返回的对象,以及所需的任何子对象 (例如如果你反序列化一个对象,包含数组,则将为此数组分配 GC 内存)。
• FromJsonOverwrite() 分配 GC 内存仅作为written 字段 (例如字符串和数组) 的必要条件。如果被覆盖 JSON 的所有字段都是值类型,它应该不会分配任何 GC 内存。

使用 JsonUtility API 从后台线程被允许。与任何多线程代码,你要小心不能访问或改变对象在一个线程上,而不是序列化/反序列化在另一个线程上。

控制 ToJson() 的输出

ToJson 支持漂亮-打印 JSON 输出。它默认是关闭的但你可以把它打开通过将 true 作为第二个参数传递。
通过使用 [NonSerialized] 属性,可以输出中省略字段。

使用 FromJson() 时事先并不知道类型

反 JSON 序列化为类或结构中包含 ‘共同’ 字段,然后使用这些字段的值上班出你想要什么实际类型。然后进行反序列化第二次到该类型。