Unity Editor模式下Serializable类字段被置零问题咨询
聊聊Unity编辑器下Serializable类的初始化坑:为什么
sides会被置0? 我刚碰到过类似的问题,太懂这种困惑了!先给你把原因讲透,再给几个编辑器模式下能用的解决方案。
为啥sides好好的6会变成0?
这完全是Unity编辑器序列化机制的“特殊操作”:
- 当你给类加上
[System.Serializable]后,Unity就会接管这个类的序列化流程。在编辑器模式下,Unity会直接忽略字段的 inline 初始化(就是private int sides = 6;这种写在字段声明里的赋值),反序列化时直接把字段设为类型默认值——int的默认值就是0。 - 但到了游戏运行模式,Unity会老老实实调用类的构造函数,这时候inline初始化会正常执行,所以
sides能保持6。 - 而用
const修饰时,sides的值会被编译成硬编码的常量,完全不参与Unity的序列化流程——Unity根本碰不到这个字段,所以不管编辑器还是运行模式,值都是6。
编辑器模式下的解决方案
给你三个实用的方案,根据你的需求选就行:
1. 把初始化移到构造函数里
既然编辑器模式下创建实例时会调用构造函数,那直接把sides的初始化逻辑放到构造函数里:
[System.Serializable] public class TestingSerializable { private int resolution; private int radius; private int sides; public TestingSerializable(int resolution, int radius) { this.resolution = resolution; this.radius = radius; this.sides = 6; // 在这里初始化 } public void PrintValue() { Debug.Log(sides); } }
这样不管是编辑器还是运行模式,构造函数都会执行,sides肯定是6。
2. 用[SerializeField] + [HideInInspector]标记字段
如果你希望sides被Unity序列化(比如要保存到场景/预制体里),但又不想在Inspector面板显示它,就给字段加这两个特性:
[System.Serializable] public class TestingSerializable { private int resolution; private int radius; [SerializeField, HideInInspector] private int sides = 6; public TestingSerializable(int resolution, int radius) { this.resolution = resolution; this.radius = radius; // 如果需要在构造时修改初始值,再在这里赋值 } public void PrintValue() { Debug.Log(sides); } }
加了[SerializeField]后,Unity的序列化系统会识别这个字段并保留它的初始值,[HideInInspector]则让它不在Inspector里显示,完美兼顾序列化和隐私。
3. 继续用const(如果值永远不变)
如果sides从始至终都是固定的6,那const绝对是最省心的选择——常量不参与Unity序列化,直接避开了这个坑,而且编译期就确定值,性能上还略优。
最后补一句
Unity编辑器的序列化系统主要是为了让你能在Inspector里编辑和保存对象状态,所以它的逻辑和纯C#不一样,很多时候会“跳过”常规的C#初始化逻辑。记住这个点,以后碰到类似的序列化问题就好排查啦。
内容的提问来源于stack exchange,提问作者Jee
相关产品推荐
相关产品推荐

