不同C#文件中类间属性异常遮蔽问题咨询
Unity中不同MonoBehaviour子类同名public字段值混淆问题
问题重现
我有两个继承自MonoBehaviour的类,分别在不同C#文件中,都定义了同名的public字段但默认值不同:
// ClassA.cs public class ClassA : MonoBehaviour { public Color lineColour = new Color(1.0f, 0.0f, 0.0f, 1.0f); // 红色 // 其他代码... }
// ClassB.cs public class ClassB : MonoBehaviour { public Color lineColour = new Color(0.0f, 0.0f, 1.0f, 1.0f); // 蓝色 // 其他代码... }
但在ClassB中使用lineColour时,获取到的却是ClassA的红色值:
// ClassB.cs 中的代码 lineRenderer.startColor = lineColour; lineRenderer.endColor = lineColour; // 实际绘制出红色线条,而非预期的蓝色
只有把ClassB中的字段名改成lineColour以外的名称,才能正常获取蓝色值。
问题原因
这不是C#语言层面的字段遮蔽行为——遮蔽仅发生在有继承关系的类之间(比如子类定义与父类同名的成员),而ClassA和ClassB是平级的无继承关系类,语言层面不可能互相干扰。
真正的问题出在Unity的序列化系统:Unity序列化组件数据时,是基于字段名称而非所属类来识别的。如果你的GameObject曾经挂载过ClassA组件,后来替换成ClassB组件,Unity会保留之前序列化的lineColour值(红色),因为字段名完全一致,Unity会默认将旧值赋值给新组件的同名字段,覆盖掉ClassB的默认蓝色值。
解决办法
- 清除序列化残留值:将ClassB组件从GameObject上移除,保存场景/预制体,再重新挂载ClassB组件。此时Unity会加载ClassB的默认字段值(蓝色)。
- 手动修正Inspector值:选中挂载ClassB的GameObject,在Inspector面板中找到
lineColour字段,手动将颜色改为蓝色并保存。 - 修改字段名(已验证有效):直接给ClassB的字段换个名称(比如
lineColorB),彻底避免Unity序列化时的字段名冲突。 - 使用序列化属性区分:如果不想修改字段名,可以给字段添加
[FormerlySerializedAs]属性(更适合字段重命名场景),确保序列化系统能正确识别字段归属。
总结
这是Unity序列化系统的特性导致的旧数据残留问题,并非C#语言的遮蔽行为。只要处理掉序列化的旧值,就能让ClassB的lineColour正常使用默认蓝色值。
内容的提问来源于stack exchange,提问作者dankal444
相关产品推荐
相关产品推荐

