ArgumentException异常排查:事件订阅时参数超出预期范围
解答
禁用状态不是异常诱因
Unity中,禁用(SetActive(false))的MonoBehaviour组件实例不会变为null,只是其生命周期函数(如Start、Update)停止执行。只要你在Inspector中正确赋值了firstScript/secondScript引用,即使脚本禁用,firstScript != null的判断依然为true,不会触发当前的参数异常。
真正的异常原因
枚举值不匹配(编译/逻辑错误)
ScriptType枚举定义的是FirstScript和SecondScript,但BossHandler的switch分支中写的是ScriptType.First和ScriptType.Second——这两个枚举值不存在,编译时就会报错。如果是输入笔误,比如实际枚举是First/Second,需修正;若代码确实如此,会导致switch不会进入任何分支,但这不是当前初始化阶段参数异常的直接原因。bossHealthBar为null(直接触发异常)
异常发生在绑定事件的代码行,核心原因是FindObjectOfType<BossHealthBar>()没有找到对应的组件实例,返回了null。此时bossHealthBar.UpdateFillers是指向null对象的方法组,Unity不允许将此类委托添加到事件中,因此抛出ArgumentException。事件调用的潜在问题
在FirstScript.HurtInAWay和SecondScript.HurtInAnotherWay中,调用bossBarUpdate.Invoke()时未传入hitpower参数,与委托定义的参数要求不符;另外,若事件未绑定订阅者,直接调用Invoke()会触发空引用异常。
解决方法
修正枚举值匹配
将switch分支中的枚举值改为与定义一致:switch (scriptType) { case ScriptType.FirstScript: if (firstScript != null) firstScript.bossBarUpdate += bossHealthBar.UpdateFillers; break; case ScriptType.SecondScript: if (secondScript != null) secondScript.bossBarUpdate += bossHealthBar.UpdateFillers; break; }确保
bossHealthBar不为null- 优先在Inspector中直接给
BossHandler的bossHealthBar字段赋值,避免依赖效率低下且不稳定的FindObjectOfType; - 若必须使用
FindObjectOfType,添加空值判断:private void Start() { bossHealthBar = FindObjectOfType<BossHealthBar>(); if (bossHealthBar == null) { Debug.LogError("未找到BossHealthBar组件!"); return; } // 后续switch逻辑 }
- 优先在Inspector中直接给
修复事件调用问题
调用事件时传入正确参数,并添加空引用防护:// FirstScript public void HurtInAWay(int hitpower) { bossBarUpdate?.Invoke(hitpower); } // SecondScript public void HurtInAnotherWay(int hitpower) { bossBarUpdate?.Invoke(hitpower); }
内容的提问来源于stack exchange,提问作者MetallicWaste

