当前位置: 首页 > web >正文

Unity3D 序列化机制:引擎内的应用场景和基本原理

前言

Unity3D 的序列化机制是其核心功能之一,用于在编辑器和运行时之间持久化数据、管理场景状态、处理预制体(Prefab)以及实现跨平台兼容性。以下是其应用场景和基本原理的详细解析:

对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交流一下开发经验呀!

一、应用场景

  1. 场景(Scene)与预制体(Prefab)的保存与加载
  • Unity 使用序列化将场景中的 GameObject、组件(Component)及其属性保存为文本或二进制格式(如 .unity 场景文件或 .prefab 文件)。
  • 预制体的实例化和修改(如覆盖属性)依赖序列化机制。
  • Inspector 面板的编辑
  • 在编辑器中,组件的公有字段(或标记了 [SerializeField] 的私有字段)通过序列化机制暴露到 Inspector 面板,修改后的值会被序列化保存。
  • ScriptableObject 数据持久化
  • ScriptableObject 的数据通过序列化存储为 .asset 文件,适用于游戏配置(如技能、物品属性)。
  • 资源热更新与跨平台兼容
  • AssetBundle 中的资源(如材质、动画)通过序列化实现跨平台兼容,确保不同平台加载时数据格式正确。
  • 运行时状态持久化
  • 游戏存档(如玩家进度、物品栏)可通过序列化(如 JsonUtility 或 BinaryFormatter)保存到本地文件。

二、基本原理

1. 序列化的条件

Unity 的序列化遵循以下规则:

  • 自动序列化的字段
    • public 字段(除非标记 [NonSerialized])。
    • 标记了 [SerializeField] 的私有/受保护字段。
  • 不序列化的字段
    • 属性(Property)、静态字段、未标记 [SerializeField] 的私有字段。
    • 标记了 [NonSerialized] 的字段。

2. 序列化流程

  • 编辑器序列化
    • 当场景或预制体保存时,Unity 将 GameObject 的层级结构和组件属性转换为 YAML 格式文本(可读性高)。
    • 示例:一个 Transform 组件的序列化结果:
Transform:m_ObjectHideFlags: 0m_Position: {x: 0, y: 0, z: 0}m_Rotation: {x: 0, y: 0, z: 0, w: 1}
  • 运行时序列化
    • 使用 JsonUtility.ToJson() 或 BinaryFormatter 将对象转换为字符串或二进制数据。

3. 序列化深度

  • Unity 支持深度序列化,递归处理对象及其子属性。
  • 例外
    • 引用类型(如 UnityEngine.Object 派生类)会被序列化为元数据(如 GUID 和文件ID),而非完整对象。
    • 循环引用可能导致序列化失败。

4. 自定义序列化

通过接口 ISerializationCallbackReceiver,开发者可以在序列化前后执行逻辑:

public class CustomData : MonoBehaviour, ISerializationCallbackReceiver
{public Dictionary<string, int> stats = new Dictionary<string, int>();// 序列化前将 Dictionary 转换为 List[SerializeField] private List<string> _keys;[SerializeField] private List<int> _values;public void OnBeforeSerialize(){_keys = new List<string>(stats.Keys);_values = new List<int>(stats.Values);}public void OnAfterDeserialize(){stats = new Dictionary<string, int>();for (int i = 0; i < _keys.Count; i++)stats.Add(_keys[i], _values[i]);}
}

三、技术细节与注意事项

  1. 版本兼容性
  • 修改类结构(如删除字段)可能导致反序列化失败,旧数据可能丢失。
  • 通过 [FormerlySerializedAs("oldFieldName")] 标记字段重命名,兼容旧数据。
  • 性能优化
  • 避免频繁序列化大型数据结构(如长列表),尤其在移动端。
  • 使用 [Serializable] 标记自定义结构体或类以支持序列化。
  • 不可序列化的类型
  • Unity 无法序列化接口(interface)、委托(delegate)或非 UnityEngine.Object 派生类。
  • 解决方法:将接口转换为具体类,或使用 ScriptableObject 封装。
  • Prefab 差异序列化
  • 预制体实例的属性覆盖(如修改 Transform 的位置)通过序列化差异实现,保存为“覆盖”数据而非完整副本。

四、调试与工具

  1. 查看序列化数据
  • 在 Unity 编辑器中选择 Assets > Open C# Project,查看 .meta 文件或 YAML 格式的预制体/场景文件。
  • 序列化检查工具
  • 使用 UnityEditor.Serialization 命名空间中的工具(如 SerializedObject 和 SerializedProperty)在 Editor 脚本中调试序列化数据。

五、总结

Unity 的序列化机制是其数据驱动的核心,理解其规则和限制能帮助开发者:

  • 避免数据丢失(如字段未正确序列化)。
  • 优化资源管理(如合理使用 ScriptableObject)。
  • 实现灵活的自定义数据持久化方案。

更多教学视频

Unity3D​www.bycwedu.com/promotion_channels/2146264125

http://www.xdnf.cn/news/6009.html

相关文章:

  • vue3项目创建-配置-elementPlus导入-路由自动导入
  • 江苏发改委回复:分时电价调整对储能项目的影响 源网荷储一体化能量管理系统储能EMS
  • 为什么企业建站或独立站选用WordPress
  • C程序的存储空间分配
  • 汉得 x 真味生物|H-ZERO PaaS项目启动,共启数字化新征程!
  • 可视化+智能补全:用Database Tool重塑数据库工作流
  • java 结合 FreeMarker 和 Docx4j 来生成包含图片的 docx 文件
  • 七、深入 Hive DDL:管理表、分区与洞察元数据
  • 邀请函|PostgreSQL培训认证报名正式开启
  • 演员评论家算法
  • LS-DYNA一箭穿心仿真分析
  • Oracle CDB 与 Non-CDB (NoCDB) 的区别
  • Linux(1)编译链接和gcc
  • typedef unsigned short uint16_t; typedef unsigned int uint32_t;
  • Lin4neuro 系统详解
  • Qt应用程序启动时的一些思路:从单实例到性能优化的处理方案
  • zabbix最新版本7.2超级详细安装部署(一)
  • VS Code怎么设置python SDK路径
  • 理解计算机系统_并发编程(5)_基于线程的并发(二):线程api和基于线程的并发服务器
  • Ascend的aclgraph(六)AclConcreteGraph
  • 技术并不能产生一个好的产品
  • solidwors插件 开发————仙盟创梦IDE
  • # YOLOv3:基于 PyTorch 的目标检测模型实现
  • 2.7/Q2,Charls最新文章解读
  • 北三短报文数传终端:筑牢水利防汛“智慧防线”,守护江河安澜
  • 构建你的第一个简单AI助手 - 入门实践
  • LangSmith 基本使用教程
  • 大疆无人机
  • 黑马k8s(五)
  • 面试题总结