使用JsonUtility类将Unity对象转换为JSON格式,并将JSON格式转换回Unity对象。例如,您可以使用JSON序列化与Web服务交互,或将数据轻松打包和展开到基于文本的格式。
JSON序列化使用“结构化”JSON的概念:您创建一个类或结构来描述您要存储在JSON数据中的变量。例如
[Serializable]
public class MyClass
{
public int level;
public float timeElapsed;
public string playerName;
}
这定义了一个包含三个变量(level、timeElapsed和Serializable
属性进行了标记,以便与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 now contains: '{"level":1,"timeElapsed":47.5,"playerName":"Dr Charles Francis"}'
要将JSON转换回对象,请使用JsonUtility.FromJson
myObject = JsonUtility.FromJson<MyClass>(json);
这会创建一个MyClass
的新实例,并使用JSON数据设置其值。如果JSON数据包含不对应MyClass
中字段的值,则序列化器会忽略这些值。如果JSON数据中缺少MyClass
中字段的值,则序列化器将返回的对象中那些字段的构建值保留。
您还可以将JSON数据反序列化到一个现有对象上,这将覆盖任何现有数据
JsonUtility.FromJsonOverwrite(json, myObject);
如果JSON数据没有为字段提供一个值,则序列化器不会更改该字段的值。此方法允许您通过重用先前创建的对象来最小化分配,还可以通过使用仅包含一小部分字段的JSON有效地“修补”对象。
警告:JSON序列化器API支持MonoBehaviour和ScriptableObject的子类,以及具有[Serializable]
属性的普通结构或类。但是,当将JSON反序列化到MonoBehaviour
或ScriptableObject
的子类时,您必须使用FromJsonOverwrite方法。如果您尝试使用FromJson,由于此行为不受支持,Unity将引发异常。
JSON序列化器API支持任何MonoBehaviour
子类、ScriptableObject
子类或具有[Serializable]
属性的普通类或结构。当您传递对象以供标准Unity序列化器处理时,将应用与Inspector中相同的规则和限制:Unity仅序列化字段;例如Dictionary<>
之类的类型不受支持。
Unity不支持将其他类型直接传递到API,例如原始类型或数组。如需转换这些类型,请将它们包装在一个class
或struct
中。
在编辑器中,还有一个并行API EditorJsonUtility,它允许您将任何从UnityEngine.Object派生的对象序列化并转换为JSON,也可以反序列化。这会产生包含与对象YAML表示形式相同数据的JSON。
JsonUtility和EditorJsonUtility是实用程序类,用于将对象序列化到JSON字符串格式以及从JSON字符串反序列化对象,使用的是Unity序列化规则。在需要通过代码操纵JSON数据或序列化Unity的序列化器不支持的数据结构的情况下,您可以使用通用的.NET JSON库作为JsonUtility API的配套工具。
基准测试表明,尽管在某些情况下这个类提供的功能更少,但JsonUtility 的速度明显快于流行的 .NET JSON解决方案。
垃圾收集(GC)的内存使用量达到最小值。
您可以在后台线程中调用 JsonUtility API。然而,与任何多线程代码一样,请小心不要在一个线程上访问或修改对象,同时另一个线程正在将其序列化或反序列化。
ToJson 方法支持漂亮的 JSON 输出。默认情况下是关闭的,但您可以通过将 true
作为第二个参数来打开。
您可以使用 [NonSerialized]
特性省略输出中的字段。
如果您事先不知道对象的类型,可以将 JSON 反序列化到一个包含“常用”字段的类或结构体,然后使用这些字段的值来确定您需要的实际类型。然后再次将 JSON 反序列化到该类型。