缺少刚体场和 ?? 的引用异常操作员

Missing Reference Exception with Rigidbody Field and ?? operator

我不断收到此异常: "MissingReferenceException: The object of type 'Rigidbody' has been destroyed but you are still trying to access it."

它的问题是我只能通过这个字段访问它:

    private Rigidbody m_Rigidbody = null;
    private Rigidbody Rigidbody => m_Rigidbody ?? (m_Rigidbody = GetComponent<Rigidbody>());

我的异常是在这一行抛出的:

    public float CurrentSpeed => (Rigidbody?.velocity.magnitude ?? 0f) * ((m_SpeedType == SpeedType.MPH)?2.23693629f : 3.6f);

我的问题是,我怎么可能得到一个空引用,即使对象有一个刚体(抛出这个异常的每个对象仍然有它的刚体活动并在错误发生时附加)。

在此先致谢,祝您有愉快的一天。

你根本不应该在继承自 UnityEngine.Object 的任何东西上使用 ???

这在某种程度上与 Unity 如何实现它们的 == and != operators internally for UnityEngine.Object(这基本上是任何组件、游戏对象、资产等的超级 class)

另见 Possible unintended bypass of lifetime check of underlying Unity engine object where the makers of the Re-Sharper Plug-In for Unity explained it further based on UnityBlog - "Custom == operator, should we keep it?"

检查 ==null 并因此也特别是使用 ? and ?? 运算符只是 bypassed UnityObject.

为什么?

从表面上看:在调用 Destroy 之后(或者例如,如果它是一个序列化字段并且尚未被引用)Unity 中的 Object 不再存在。 但是不是真的==null,它仍然保存一些元数据并且只是-他们如何陈述它

a fake null object.

这实际上就是为什么你没有得到 NullReferenceException 但 Unity 内置 MissingReferenceException 给你一个提示 为什么 你通常会得到a NullReferenceException 此时。它可以例如状态

The object of type 'XY' was destroyed but you are still trying to access it


但是特别是由于这个原因 UnityEngine.Object 有一个隐含的 bool operator 返回

Does the object exist?

例如if(destroyedObject)detroyedObject 被调用后 Destroy(destroyedObject); 或者它是一个从未被分配但现在不会被执行的字段(不再),因为它现在是 false.


所以你想做的事情,特别是对 Destroyed 的东西,实际上是使用像

这样的运算符
private Rigidbody m_Rigidbody = null;
private Rigidbody Rigidbody
{
    get
    {
        if(m_Rigidbody) return m_Rigidbody;

        m_Rigidbody = GetComponent<Rigidbody>();

        return m_Rigidbody;
    }
}

出于可读性原因,我不喜欢将这样的东西作为表达式主体。

你的另一个 属性 相应地也会是

public float CurrentSpeed => Rigidbody ? Rigidbody.velocity.magnitude * ((m_SpeedType == SpeedType.MPH) ? 2.23693629f : 3.6f) : 0f;

总的来说,我的意见是:只要 属性 中可能隐藏着更多的工作,那么只是简化引用(就像这里的 GetComponent)它应该是一种方法。但也许这只是一个品味问题。