Unity中DestroyChest方法已做非空校验仍抛出NullReferenceException原因咨询
NullReferenceException 触发原因
核心根因是 Unity 自定义空判断逻辑与 C# 原生空条件运算符的兼容性问题,具体拆解如下:
- 所有继承自
UnityEngine.Object的类型(包括你用到的 MonoBehaviour、GameObject)都重载了==/!=运算符:当对象被销毁、或未挂载到激活场景的对象上时,用== null判断会返回true,但此时该对象在 C# 原生层面的引用并不是真正的空,属于 Unity 特有的「伪空」状态。 - 代码中使用的
?.是 C# 原生的空条件运算符,它只会校验 C# 层面的引用是否为真·空,完全不识别 Unity 的「伪空」状态。 - 异常触发流程:
- 当 Chest 已经被销毁(处于伪空状态)时,你的 if 判断走 Unity 重载的
!=逻辑,Chest != null结果为 false,if 块完全不会执行,你写的异常日志永远不会被触发。 - 执行
Destroy(Chest?.gameObject)时,?.检测到 Chest 在 C# 层面是非空引用,就会继续访问它的gameObject属性,但此时 Chest 已经被销毁,访问属性就会直接抛出 NullReferenceException。
- 当 Chest 已经被销毁(处于伪空状态)时,你的 if 判断走 Unity 重载的
- 额外边界场景:就算你做了前置非空判断,也可能因为帧间隔/多逻辑执行顺序问题,在 if 判断完成后、执行 Destroy 前,Chest 被其他逻辑销毁,同样会触发异常。
修复方案
替换掉 C# 原生空条件运算符,改用 Unity 兼容的显式空判断即可,参考修改后的代码:
private void DestroyChest() { // 走Unity重载的空判断,兼容伪空状态 if (Chest == null) return; if (Chest.gameObject == null) { Debug.LogException(new Exception("Chest.Gameobject is null!")); return; } Destroy(Chest.gameObject); }
内容的提问来源于stack exchange,提问作者T. Grumser
相关产品推荐
相关产品推荐

