# JSON 序列化

> Convert Unity objects to and from JSON format using the JsonUtility class.

使用 [JsonUtility](/engine/6000.0/script-reference/unity-engine/json-utility.md) 类即可将 Unity 对象转换为 [JSON](http://www.json.org) 格式，反之亦可。例如，您可以使用 JSON 序列化与 Web 服务进行交互，或者轻松地将数据压缩或解压为基于文本的格式。

JSON 序列化使用了“结构化”JSON 的概念：创建一个类或结构来描述将在 JSON 数据中存储的变量。例如：

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

此代码段定义了一个包含三个变量（**level**、**timeElapsed** 以及 **playerName**）的普通 C# 类，并用 `Serializable` 属性标记该类，以供 JSON 序列化程序使用。要创建类的实例，可以使用如下所示的代码：

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

然后使用 [JsonUtility.ToJson](/engine/6000.0/script-reference/unity-engine/json-utility/to-json.md) 方法将其序列化（转换）为 JSON 格式：

```c#
string json = JsonUtility.ToJson(myObject);
// json now contains: '{"level":1,"timeElapsed":47.5,"playerName":"Dr Charles Francis"}'
```

要将 JSON 转换回对象，请使用 [JsonUtility.FromJson](/engine/6000.0/script-reference/unity-engine/json-utility/from-json.md)：

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

这会创建一个新的 `MyClass` 实例，并使用 JSON 数据设置该实例的值。如果 JSON 数据中包含的某些值未映射到 `MyClass` 中的字段，那么序列化程序会忽略这些值。如果 JSON 数据缺少 `MyClass` 中某些字段的值，则序列化程序会在返回的对象中保留这些字段的构造值。

## 用 JSON 覆盖对象##overwriting-objects-with-json

还可以在现有对象上反序列化 JSON 数据，从而覆盖所有现有数据：

```
JsonUtility.FromJsonOverwrite(json, myObject);
```

如果 JSON 数据不包含某个字段的值，则序列化程序不会更改该字段的值。此方法可重复使用先前创建的对象，从而将分配工作保持在最低程度。此方法还允许您故意用仅包含一小部分字段的 JSON 来覆盖对象以便“修补”该对象。

\*\*警告：\*\*JSON 序列化程序的 API 支持 [MonoBehaviour](/engine/6000.0/script-reference/unity-engine/mono-behaviour.md) 和 [ScriptableObject](/engine/6000.0/script-reference/unity-engine/scriptable-object.md) 子类以及普通的结构体和类。但将 JSON 反序列化为 `MonoBehaviour` 或 `ScriptableObject` 的子类时，则必须使用 [FromJsonOverwrite](/engine/6000.0/script-reference/unity-engine/json-utility/from-json-overwrite.md) 方法。如果使用 [FromJson](/engine/6000.0/script-reference/unity-engine/json-utility/from-json.md)，那么 Unity 会抛出异常，因为此行为不受支持。

## 支持的类型##supported-types

JSON 序列化程序 API 支持所有 `MonoBehaviour` 子类、`ScriptableObject` 子类或拥有 `[Serializable]` 属性的普通类和结构体。将对象传入到标准 Unity 序列化程序进行处理时，需要遵循的规则和限制与检视面板中相同：Unity 只序列化字段；不支持类似 `Dictionary<>` 的类型。

Unity 不支持将其他类型直接传给 API，例如原始类型或数组。如果需要转换上述类型，请将它们包裹在某种 `class` 或 `struct` 中。

仅在编辑器中存在一个并行 API，即 [EditorJsonUtility](/engine/6000.0/script-reference/unity-editor/editor-json-utility.md)，可以让您将派生于 [UnityEngine.Object](/engine/6000.0/script-reference/unity-engine/object.md) 的对象序列化为 JSON，反之亦可。这样生成的 JSON 将包含与对象的 YAML 表示相同的数据。

[JsonUtility](/engine/6000.0/script-reference/unity-engine/json-utility.md) 和 [EditorJsonUtility](/engine/6000.0/script-reference/unity-editor/editor-json-utility.md) 都是实用程序类，可用于按 [Unity 序列化规则](/engine/6000.0/manual/scripting/compilation-and-code-reload/script-serialization.md#SerializationRules)将对象序列化为 JSON 字符串格式（或反之）。如果需要通过代码操作 JSON 数据，或为不支持 Unity 序列化的数据结构进行序列化，可以搭配通用 .NET JSON 库使用 JsonUtility API。

## 性能##performance

基准测试表明 [JsonUtility](/engine/6000.0/script-reference/unity-engine/json-utility.md) 显著地快于流行的 .NET JSON 解决方案，尽管此类在某些情况下提供的功能较少。

垃圾收集 (GC) 内存使用量为最低量：

* [ToJson](/engine/6000.0/script-reference/unity-engine/json-utility/to-json.md) 仅为返回的字符串分配 GC 内存。
* [FromJson](/engine/6000.0/script-reference/unity-engine/json-utility/from-json.md) 仅为返回的对象以及所需的子对象分配 GC 内存（例如，如果对包含数组的对象进行反序列化，则 Unity 将为该数组分配 GC 内存）。
* [FromJsonOverwrite](/engine/6000.0/script-reference/unity-engine/json-utility/from-json-overwrite.md) 仅按需为写入的字段（例如字符串和数组）分配 GC 内存。这意味着，如果 JSON 覆盖的所有字段都是值类型，则 Unity 不会分配任何 GC 内存。

您可以在后台线程中使用 JsonUtility API。但就和任何多线程代码一样，当一个线程正在序列化或反序列化对象时，请勿在另一个线程上访问或更改该对象。

## 控制 ToJson() 的输出##controlling-the-output-of-tojson()

[ToJson](/engine/6000.0/script-reference/unity-engine/json-utility/to-json.md) 支持完美打印 JSON 输出。此功能默认为关闭状态，但可通过传递 `true` 作为第二个参数来打开此功能。

可以使用 `[NonSerialized]` 属性在输出中省略字段。

## 使用包含未知类型的 FromJson()##using-fromjson()-with-unknown-types

如果事先不知道对象的类型，请将 JSON 反序列化为包含“公共”字段的类或结构，然后使用这些字段的值来判断所需的实际类型。然后第二次反序列化为该类型。
