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

Unity中使用继承时列表内对象运行时为空的问题

Unity中继承MonoBehaviour的子类列表运行时引用为空的解决方法

问题根源

Unity对继承自MonoBehaviour的组件引用序列化有特殊限制:当你在Inspector中将挂载了Activable子类(如FM)的组件拖入List<Activable>时,编辑状态下Unity能显示引用,但运行时无法正确还原子类组件的引用,导致列表项为null。

[SerializeReference]特性在此场景不适用——它仅用于序列化非MonoBehaviour/ScriptableObject的普通引用类型,对Unity场景中的组件对象无效。而直接使用基类Activable组件时能正常工作,是因为Unity可以直接序列化基类型的组件引用。

可行解决方案

方法1:改用List<GameObject>存储对象,运行时动态获取组件

修改基类Activator的代码,通过存储GameObject引用,在运行时主动获取Activable子类组件:

public class Activator : MonoBehaviour
{
    // 在Inspector中拖入挂载了Activable子类的GameObject
    public List<GameObject> activableGameObjects;
    private List<Activable> objectsToActivate = new List<Activable>();

    public virtual void Start()
    {
        objectsToActivate.Clear();
        foreach (var go in activableGameObjects)
        {
            var activable = go.GetComponent<Activable>();
            if (activable != null)
            {
                objectsToActivate.Add(activable);
                Debug.Log(activable);
            }
            else
            {
                Debug.LogWarning($"GameObject {go.name} 未挂载Activable或其子类组件");
            }
        }
    }
}

这种方式利用Unity对GameObject引用的可靠序列化机制,确保运行时能正确获取到对应的子类组件。

方法2:使用[SerializeField]配合显式类型声明(可选)

如果坚持要直接存储组件引用,可以在子类中添加显式的序列化字段,但这种方式扩展性较差,仅适用于固定子类:

public class SpecificActivator : Activator
{
    [SerializeField] private List<FM> fmObjects;

    public override void Start()
    {
        base.Start();
        objectsToActivate.AddRange(fmObjects);
        // 后续逻辑处理
    }
}

但这种方法仅支持特定子类,不如方法1灵活。

验证步骤

  1. 将原List<Activable>替换为List<GameObject>(方法1)
  2. 在Inspector中重新拖入所有挂载了FM组件的GameObject
  3. 运行游戏,检查控制台输出,确认组件引用正常

内容的提问来源于stack exchange,提问作者Manuel A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 13:16:04