You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不同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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 20:43:51