Version: 6000.3
语言: 中文
自定义序列化
JSON 序列化

Unity 如何使用序列化

保存和加载

Unity 使用序列化来加载和保存场景场景包含游戏的环境和菜单。将每个唯一的场景文件视为一个独特的关卡。在每个场景中,你放置你的环境、障碍物和装饰品,基本上是将你的游戏设计和构建成碎片。更多信息
请参阅术语表
,资产可在游戏或项目中使用的任何媒体或数据。资产可能来自在 Unity 外部创建的文件,例如 3D 模型、音频文件或图像。您还可以在 Unity 中创建一些资产类型,例如动画师控制器、混音器或渲染纹理。更多信息
请参阅术语表
,以及与设备内存相连的 AssetBundle。这包括保存在您自己的脚本 API 对象中的数据,例如 MonoBehaviour 组件和 ScriptableObjects

Unity 编辑器中的许多功能都是建立在核心序列化系统之上的。序列化时需要特别注意的两件事是 Inspector 窗口和热重载。

“检查器”窗口

检查器一个 Unity 窗口,显示有关当前选定游戏对象、资产或项目设置的信息,允许您检查和编辑值。更多信息
请参阅术语表
窗口显示被检查对象的序列化字段的值。更改检查器中的值时,检查器会更新序列化数据并触发反序列化以更新检查对象。

这同样适用于内置 Unity 对象和脚本对象,例如 MonoBehaviour 派生类。

在检查器窗口中查看或更改值时,Unity 不会调用任何 C# 属性 getter 和 setter。相反,Unity 直接访问序列化的支持字段。

热重载

脚本代码的热重载作为资产数据库刷新的一部分执行。它是指在编辑器运行时直接重新加载和应用代码更改的过程,而无需重新启动它。有关更多信息,请参阅刷新资产数据库热重载

注意:热重载是一种特殊的序列化情况。与其他序列化情况不同,Unity 在重新加载时默认序列化私有字段,即使它们没有 SerializeField 属性。

当 Unity 重新加载时脚本一段代码,允许您创建自己的组件、触发游戏事件、随时间修改组件属性以及以您喜欢的任何方式响应用户输入。更多信息
请参阅术语表
:

  1. Unity 序列化并存储所有加载脚本中的所有变量。
  2. Unity 将它们恢复到原始的序列化前值:
    • Unity 会恢复所有满足序列化要求的变量(包括私有变量),即使变量没有[SerializeField]属性。有时,您需要阻止 Unity 恢复私有变量,例如,如果您希望从脚本重新加载后引用为 null。在这种情况下,请使用[field: NonSerialized]属性。
    • Unity 从不恢复静态变量,因此不要将静态变量用于 Unity 重新加载脚本后需要保留的状态,因为重新加载过程会丢弃它们。

预制件

一个预制件:一种资产类型,允许您存储包含组件和属性的游戏对象。预制件充当模板,你可以从中在场景中创建新的对象实例。更多信息
请参阅术语表
是一个或多个的序列化数据游戏对象Unity 场景中的基本对象,可以表示角色、道具、风景、相机、航路点等。游戏对象的功能由附加到它的组件定义。更多信息
请参阅术语表
组件游戏对象的功能部分。游戏对象可以包含任意数量的组件。Unity 有许多内置组件,您可以通过编写继承自 MonoBehaviour 的脚本来创建自己的组件。更多信息
请参阅术语表
.预制件实例包含对预制件源的引用和对其修改的列表。这些修改是 Unity 需要对预制件源代码执行的作,以创建该特定的预制件实例。

预制件实例仅在您在 Unity 编辑器中编辑项目时存在。Unity 编辑器从其两组序列化数据中实例化游戏对象:预制件源和预制件实例的修改。

实例

当您调用Instantiate在场景中存在的任何内容上,例如预制件或游戏对象:

  1. Unity 对其进行序列化。这在运行时和编辑器中都会发生。Unity 可以序列化派生自UnityEngine.Object.
  2. Unity 创建一个新的游戏对象,并将数据反序列化到新的游戏对象上。
  3. Unity 在不同的变体中运行相同的序列化代码,以报告其他UnityEngine.Objects它引用。它检查所有引用的UnityEngine.Objects以确定它们是否是 Unity 实例化数据的一部分。如果引用指向外部内容(例如纹理),则 Unity 会保持该引用不变。如果引用指向内部内容(例如子游戏对象),则 Unity 会修补对相应副本的引用。

卸载未使用的资产

EditorUtility.UnloadUnusedAssetsImmediate是本机 Unity 垃圾回收器,其用途与标准 C# 垃圾回收器不同。它在加载场景后运行,并检查它不再引用的对象(如纹理),并安全地卸载它们。本机 Unity 垃圾回收器以变体运行序列化程序,其中对象报告对外部的所有引用UnityEngine.Objects.这就是一个场景使用的纹理,垃圾回收器在下一个场景中卸载的方式。

编辑器序列化和运行时序列化之间的区别

大多数序列化发生在编辑器中,而反序列化是运行时的重点。Unity 仅在编辑器中序列化某些功能,而它可以在编辑器和运行时序列化其他功能:

特征 编辑 器 运行
二进制格式的资产 支持读/写 支持读取
YAML 格式的资产 支持读/写 不支持
保存场景、预制件和其他资产 支持,除非处于播放模式 不支持
使用 JsonUtility 序列化单个对象 使用 JsonUtility 的读/写支持。

使用 EditorJsonUtility 支持其他类型的对象
使用 JsonUtility 的读/写支持
序列化引用 支持 支持
ISerializationCallbackReceiver 支持 支持
Formerly序列化为 支持 不支持

对象可以具有只有编辑器序列化的其他字段,例如,当您在UNITY_EDITOR脚本符号中声明字段时:

public class SerializeRules : MonoBehaviour
{
#if UNITY_EDITOR
public int m_intEditorOnly;
#endif
}

在前面的示例中,m_intEditorOnly字段仅在编辑器中序列化,不包含在构建中。这允许你通过从构建中省略编辑器中仅需要的数据来节省内存。使用该字段的任何代码也需要有条件地编译,例如在#if UNITY_EDITOR块,以便类可以在构建时编译。

编辑器不支持具有 Unity 仅在运行时序列化的字段的对象(例如,当您在 UNITY_STANDALONE 指令中声明字段时)。

其他资源

自定义序列化
JSON 序列化