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.mzph.cn/diannao/82924.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 字典键 “三变一” 之谜

开头&#xff1a;读者的“玄学”字典谜题 上周&#xff0c;朋友发来了一段让他抓耳挠腮的代码&#xff1a; >>> {True: foo, 1: bar, 1.0: baz} {True: baz} “我明明定义了布尔True、整数1、浮点数1.0三个键&#xff0c;结果字典里只剩True一个键&#xff0c;值…

如何选择 RabbitMQ、Redis 队列等消息中间件?—— 深度解析与实战评估

如何选择 RabbitMQ、Redis 队列等消息中间件?—— 深度解析与实战评估 1. 引言 在现代分布式系统架构中,消息队列(Message Queue,MQ) 作为解耦服务、异步处理和高效通信的关键组件,被广泛应用于高并发、微服务和数据流处理场景。选择合适的消息中间件不仅能提高系统的稳…

特征工程四:数据特征提取TfidfVectorizer的使用

TfidfVectorizer 深度解析 TfidfVectorizer 是 scikit-learn 中用于文本特征提取的核心工具&#xff0c;它将原始文本转换为 TF-IDF 特征矩阵&#xff0c;是自然语言处理(NLP)和文本挖掘的基础组件。 一、核心原理 1. TF-IDF 计算 TF (Term Frequency)&#xff1a;词频&…

c/c++爬虫总结

GitHub 开源 C/C 网页爬虫探究&#xff1a;协议、实现与测试 网页爬虫&#xff0c;作为一种自动化获取网络信息的强大工具&#xff0c;在搜索引擎、数据挖掘、市场分析等领域扮演着至关重要的角色。对于希望深入理解网络工作原理和数据提取技术的 C/C 开发者&#xff0c;尤其是…

PostgreSQL 的表连接方法

PostgreSQL 的表连接方法 PostgreSQL 提供了多种高效的连接算法&#xff0c;每种方法适用于不同的查询场景。以下是 PostgreSQL 支持的四种主要表连接方法及其特点&#xff1a; 1 Nested Loop Join&#xff08;嵌套循环连接&#xff09; 工作原理 对外表的每一行&#xff0…

【Qt】qss语法详解

QSS (Qt Style Sheets) 语法格式详解 QSS 是 Qt 的样式表语言&#xff0c;类似于 CSS&#xff0c;用于自定义 Qt 应用程序的外观。以下是 QSS 的完整语法格式说明&#xff1a; 基本语法结构 selector {property: value;property: value;... }1. 选择器 (Selectors) 基本选择…

Azure资源创建与部署指南

本文将指导您如何在Azure平台上创建和配置必要的资源,以部署基于OpenAI的应用程序。 资源组创建 资源组是管理和组织Azure资源的逻辑容器。 在Azure门户顶端的查询框中输入"Resource groups"(英文环境)或"资源组"(中文环境)在搜索结果中点击"资…

Java后端快速生成验证码

Hutool是一个小而全的Java工具类库&#xff0c;它提供了很多实用的工具类&#xff0c;包括但不限于日期处理、加密解密、文件操作、反射操作、HTTP客户端等。 核心工具类&#xff1a;CaptchaUtil&#xff0c;CaptchaUtil 是 Hutool 提供的一个工具类&#xff0c;用于创建各种类…

sql 备份表a数据到表b

备份表a数据到表b mysql CREATE TABLE sys_dict_240702 LIKE sys_dict;INSERT INTO sys_dict_240702 SELECT * FROM sys_dict;mssql select * into t_Dict_240702 from t_Dict

2.4GHz无线通信芯片选型指南:集成SOC与低功耗方案解析

今天给大家分享几款2.4GHz无线通信芯片方案&#xff1a; 一、集成SOC芯片方案 XL2407P&#xff08;芯岭技术&#xff09; 集成射频收发机和微控制器&#xff08;如九齐NY8A054E&#xff09; 支持一对多组网和自动重传 发射功率8dBm&#xff0c;接收灵敏度-96.5dBm&#xff08…

Tomcat与纯 Java Socket 实现远程通信的区别

Servlet 容器​​&#xff08;如 Tomcat&#xff09; 是一个管理 Servlet 生命周期的运行环境&#xff0c;主要功能包括&#xff1a; ​​协议解析​​&#xff1a;自动处理 HTTP 请求/响应的底层协议&#xff08;如报文头解析、状态码生成&#xff09;&#xff1b; ​​线程…

[超级简单]讲解如何用PHP实现LINE Pay API!

在 PHP 中实现 LINE Pay API 之前我应该​​做哪些准备&#xff1f;如何在 PHP 中实现 LINE Pay API&#xff1f; 目录 [前提] 环境使用 PHP 实现 LINE Pay API 的准备工作使用 PHP 实现 LINE Pay API概括 [前提] 环境 这次我们将使用SandBox环境&#xff08;测试环境&a…

centos7.x下,使用宝塔进行主从复制的原理和实践

操作原理&#xff1a; 一、主库配置 1.修改 MySQL 配置文件 # 编辑主库配置文件&#xff08;路径根据实际系统可能不同&#xff09; vim /etc/my.cnf # 添加以下配置 [mysqld] server-id 1 # 唯一 ID&#xff0c;主库设置为 1 log-bin mysql-bin …

从零实现基于Transformer的英译汉任务

1. model.py&#xff08;用的是上一篇文章的代码&#xff1a;从0搭建Transformer-CSDN博客&#xff09; import torch import torch.nn as nn import mathclass PositionalEncoding(nn.Module):def __init__ (self, d_model, dropout, max_len5000):super(PositionalEncoding,…

c#建筑行业财务流水账系统软件可上传记账凭证财务管理系统签核功能

# financial_建筑行业 建筑行业财务流水账系统软件可上传记账凭证财务管理系统签核功能 # 开发背景 软件是给岳阳客户定制开发一款建筑行业流水账财务软件。提供工程签证单、施工日志、人员出勤表等信息记录。 # 财务管理系统功能描述 1.可以自行设置记账科目&#xff0c;做凭…

MySQL 8.0 OCP 1Z0-908 题目解析(2)

题目005 Choose two. Which two actions can obtain information about deadlocks? □ A) Run the SHOW ENGINE INNODB MUTEX command from the mysql client. □ B) Enable the innodb_status_output_locks global parameter. □ C) Enable the innodb_print_all_deadlock…

XA协议和Tcc

基于 XA 协议的两阶段提交 (2PC)。这是一种分布式事务协议&#xff0c;旨在保证在多个参与者&#xff08;通常是不同的数据库或资源管理器&#xff09;共同参与的事务中&#xff0c;所有参与者要么都提交事务&#xff0c;要么都回滚事务&#xff0c;从而维护数据的一致性。 你…

数据分析-图2-图像对象设置参数与子图

from matplotlib import pyplot as mp mp.figure(A figure,facecolorgray) mp.plot([0,1],[1,2]) mp.figure(B figure,facecolorlightgray) mp.plot([1,2],[2,1]) #如果figure中标题已创建&#xff0c;则不会新建窗口&#xff0c; #而是将旧窗口设置为当前窗口 mp.figure(A fig…

跳转语句:break、continue、goto -《Go语言实战指南》

在控制流程中&#xff0c;我们有时需要跳出当前循环或跳过当前步骤&#xff0c;甚至直接跳转到指定位置。Go 提供了三种基本跳转语句&#xff1a; • break&#xff1a;跳出当前 for、switch 或 select。• continue&#xff1a;跳过本轮循环&#xff0c;进入下一轮。• goto&a…

Linux中find命令用法核心要点提炼

大家好&#xff0c;欢迎来到程序视点&#xff01;我是你们的老朋友.小二&#xff01; 以下是针对Linux中find命令用法的核心要点提炼&#xff1a; 基础语法结构 find [路径] [选项] [操作]路径&#xff1a;查找目录&#xff08;.表当前目录&#xff0c;/表根目录&#xff09;…