我直接给你最清晰、最准确、Unity 官方定义的答案:
你在 Unity 写代码、做项目时,到底哪些操作算序列化,我一次性给你讲全,让你以后再也不混淆。
先记住一句话(核心)
Unity 序列化 = 把 "内存里的对象 / 数据" 变成 "能存进磁盘文件" 的格式
只要满足这个,就是序列化。
一、你写代码时 一定会触发序列化 的情况
1. 把脚本挂在 GameObject 上,保存场景 ✅ 序列化
你写:
csharp
运行
public class Player : MonoBehaviour
{
public int hp; // 被序列化
public string name; // 被序列化
}
然后拖到物体上 → 保存场景。
发生了什么:
Unity 把你这个脚本实例化后的对象数据 ,转成二进制,存进 .unity 场景文件里。
→ 这就是序列化
2. 脚本里的 public 字段 / [SerializeField] 出现在 Inspector ✅ 序列化
只要你在 Inspector 面板能看到、能改的值,全部都被 Unity 序列化了。
csharp
运行
public int id; // 序列化
SerializeField\] private float speed; // 序列化 → 这些值会被存到场景 / 预制体里。 ### 3. ScriptableObject 你创建文件、填数据 ✅ 序列化 你说的这个 ****完全正确****。 csharp 运行 \[CreateAssetMenu
public class GameData : ScriptableObject
{
public string[] names;
}
你在 Project 面板右键创建它 → 填数据 → 保存。
→ 数据被序列化存成 .asset 文件
→ 这是最典型的 Unity 序列化。
4. 预制体(Prefab)上挂的脚本数据 ✅ 序列化
你做一个预制体,上面有脚本、有数值。
保存预制体 = 序列化所有脚本里的可序列化字段。
5. 你手动调用 JsonUtility / BinaryFormatter 存数据 ✅ 序列化
csharp
运行
JsonUtility.ToJson(数据);
这是代码级序列化。
二、写代码时 绝对不算序列化 的
1. 普通脚本里写逻辑、变量、字典、List 等 ✅ 不序列化
csharp
运行
public Dictionary<int,string> data; // 不序列化
private int a; // 不序列化
void Update(){} // 代码不序列化
这些只存在于 DLL 里的指令,不是序列化。
2. 脚本编译成 DLL ✅ 不序列化
编译 = 转 IL 指令
不是把对象转二进制,所以不是序列化。
3. 运行时内存里创建的对象 ✅ 不序列化
运行时 new 出来的字典、list、对象
关游戏就没,没有存磁盘 → 不序列化。
三、最简单判断方法(1 秒识别)
你只要问自己一句话:
这个数据关掉 Unity 再打开还在不在?
- 还在 = 被序列化了
- 没了 = 没序列化
超级准。
四、你最关心的总结(极简版)
✅ 算序列化(存磁盘)
- 脚本挂物体,保存场景
- Inspector 能看到的字段
- ScriptableObject .asset 文件
- 预制体里的脚本数据
- JsonUtility 保存数据
❌ 不算序列化(不存磁盘)
- 普通脚本代码
- 编译成 DLL
- 字典、private 变量(默认不序列化)
- 运行时内存里的对象
最终一句话(你必须记住)
Unity 序列化 = 把数据永久保存到文件里(场景、预制体、asset)。
写代码、编译、运行时内存创建 = 都不是序列化。
总结
- ScriptableObject = 序列化 ✅
- MonoBehaviour 面板可见字段 = 序列化 ✅
- 普通脚本代码 = 不序列化 ❌
- 编译成 DLL = 不序列化 ❌
- 运行时内存数据 = 不序列化 ❌
你现在是不是 100% 通透了?
我还能给你讲:Unity 到底能序列化哪些类型,不能序列化哪些(比如字典为什么不能序列化)。
我的感觉是 当我在使用unity时需要我修改某个文件的情况下就会涉及 序列化 因为unity的资产文件有很多
你的直觉非常准 ,核心抓到了👍
先定一句总纲:
Unity 里只要是编辑器里改资产 / 场景 / 预制,保存到磁盘
**.unity/.prefab/.asset**这类文件 ,背后一定走 Unity 原生序列化 ;纯写代码、编译 dll、运行时临时 new 对象,不碰资产文件保存,就和 Unity 序列化无关。
一、先纠正 + 精炼你的理解
✅ 正确部分:
修改Unity 专属资产文件 (场景、预制、ScriptableObject、材质、动画等)→ 点击保存 / 应用 → 引擎把内存里的对象数据序列化写入磁盘文件
❌ 误区区分:
改 .cs 脚本代码文本 → 只是文本保存,不是 Unity 序列化,后续编译成 dll 也不是序列化。
二、哪些「改文件」是真・Unity 序列化
1. 改场景 .unity
拖物体、改 Inspector 参数、加脚本赋值 → Ctrl+S 保存场景
👉 引擎序列化所有可序列化字段,写入场景二进制
2. 改预制 .prefab
编辑预制内部参数、脚本公开字段 → 保存预制
👉 序列化写入 prefab 资产
3. 改 ScriptableObject .asset
创建 SO、在 Inspector 填数组 / 结构体 / 数值 → 保存
👉 最典型的自定义配置序列化
4. 改自带资源:材质 / 贴图 / 动画 / FBX 导入设置
调整参数、重新导入 → 引擎序列化配置到资产元数据
5. 自己代码存存档:Json / 二进制 / PlayerPrefs
手动把运行时内存数据落地磁盘 → 自定义序列化,不属于 Unity 引擎原生资产序列化
三、哪些「改文件」❌ 不算 Unity 序列化
- 手写 / 修改
.cs脚本源码(纯文本保存) - Unity 编译脚本生成
Assembly-CSharp.dll(IL 指令 + 常量,编译≠序列化) - 运行时内存里
new Dictionary<,>()临时数据(只在内存,不落地)
四、结合你之前的「字典」例子对比
情况 A:硬编码写在 MonoBehaviour 里
csharp
运行
public class Test : MonoBehaviour
{
// 无法被Unity原生序列化显示在面板、存场景
Dictionary<int,string> dict = new();
}
改代码→保存 cs→编译 dll:无 Unity 序列化
情况 B:用可序列化结构 + Inspector / 场景保存
csharp
运行
System.Serializable
public struct ItemData
{
public int id;
public string name;
}
public List itemList; // Inspector可见
在面板填数据→保存场景:✅ Unity 原生序列化落地磁盘
情况 C:塞 ScriptableObject
SO 里配 List / 自定义序列化结构→保存 .asset:✅ 强序列化
五、一句极简收口
只要是 Unity 编辑器内可视化改资源 / 场景 / 预制 / SO + 保存资产文件 ,就一定触发 Unity 引擎序列化;
改代码文本、编译 dll、运行时纯内存对象,都不触发 Unity 资产序列化。