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

Unity自定义编辑器中MonoBehaviour子类构造后返回null问题求助

问题根本原因

你违反了Unity引擎的核心开发规则:所有继承自MonoBehaviour的类,禁止使用new关键字手动调用构造函数实例化。
Unity对MonoBehaviour有独立的生命周期管理逻辑,直接new出来的实例没有绑定到GameObject,也没有被Unity引擎的对象系统注册,所以虽然构造函数的代码会正常执行(你能看到内部的Debug输出),但Unity的自定义空值判断逻辑会将这个非法实例判定为null,打印输出自然为null,调用方法也会抛出空引用异常。

正确的实现步骤

你需要先创建承载组件的GameObject,再挂载ComponentSlot组件,最后手动赋值参数替代原有构造函数逻辑:

  1. 删除ComponentSlot类中自定义的带参构造函数,MonoBehaviour使用自定义带参构造函数会导致序列化逻辑异常。
  2. 将Editor代码中创建实例的逻辑替换为如下代码:
[CustomEditor(typeof(ComponentMasterBase), true)]
public class ComponentMasterEditor : Editor
{
    public override void OnInspectorGUI()
    {
       ComponentMasterBase cmb = (ComponentMasterBase)target;

       // 无关逻辑保留


        if(GUILayout.Button("Add " + cmb.GetComponentType().DisplayName + " Slot"))
        {
            // 先创建承载ComponentSlot的GameObject
            GameObject slotObj = new GameObject("Component Slot");
            // 挂载组件获取合法实例
            ComponentSlot c = slotObj.AddComponent<ComponentSlot>();
            // 手动赋值参数替代原有构造函数逻辑
            c.Size = 1;
            c.SetComponent(null);
            c.ComponentType = cmb.GetComponentType();
            c.Owner = cmb;
            // 此时c为合法非空实例
            Debug.Log(c);
            cmb.AttachComponentSlot(c);

            // 可选补充:如果需要支持编辑器撤销、修改能保存到场景,加入以下代码
            Undo.RegisterCreatedObjectUndo(slotObj, "Add Component Slot");
            EditorUtility.SetDirty(slotObj);
            EditorUtility.SetDirty(cmb);
        }
    }
}

小提示:如果ComponentSlot需要通用的初始化逻辑,可以将原来构造函数内的逻辑封装为独立的Init公共方法,避免多处赋值重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 16:45:02