c# - 检查是否在 Unity3D 2019.3.05f 中的检查器中分配了 GameObject

标签 c# unity3d isnull

问题:

How to check if a public gameObject of a MonoBehaviour has been assigned in the inspector in Unity3D, as the comparison for null (object==null) fails.



具体示例:

我即将为 Unity3D 编写一个通用方法,该方法可以在任何可空对象上调用。它检查对象是否为空,如果是,则写入 Debug.LogError(customMessage) .该方法如下所示:
 public static bool IsNull<T>([CanBeNull] this T myObject, string message = "")
 {
     if (myObject!= null) return false;
     Debug.LogError("The object is null! " + message);
     return true;
 }

该方法可以在代码中的任何位置的任何可为空对象上调用,例如在这个简单的 Monobehaviour 中:
public class TestScript : MonoBehaviour
{
    public GameObject testObject = null;

    public void TestObject()
    {
        var result = testObject.IsNull("Error message");
        Debug.Log(result);
        Debug.Log(testObject);
    }
}

对于大多数用例,我的方法运行良好,并在编码/调试期间节省了大量时间。但我现在的问题是,如果我没有在编辑器中签署“testObject”,我的测试将无法工作,因为 testObject 似乎不为空,但它也无法使用,因为它没有被分配。在这种情况下,控制台输出是:

False
null



怎么来的(myObject == null)是假的,而 Debug.Log(testObject)给我 null只要相应的对象尚未在统一检查器中分配。

编辑/解决方案:
感谢 derHugo 的帮助,我最终得到了这个通用代码片段:
 public static bool IsNull<T>(this T myObject, string message = "") where T : class
    {
        switch (myObject)
        {
            case UnityEngine.Object obj when !obj:
                Debug.LogError("The object is null! " + message);
                return true;
            case null:
                Debug.LogError("The object is null! " + message);
                return true;
            default:
                return false;
        }
    }

最佳答案

Unity 有一个自定义的相等实现 ==运算符(请参阅 Custom == operator, should we keep it?,这通常会导致混淆/意外行为。
即使是 UnityEngine.Object具有等于​​ null 的值有时不是 == null .Object而是仍然在其中存储一些元数据,例如你会得到一个 MissingReferenceException , 不常见 NullReferenceException因为 Unity 实现了一些自定义异常,这些异常通常包含更多详细信息到 为什么该值等于 null .
特别是从

public GameObject testObject = null;
public字段它是自动 连载 因此 null在序列化过程中,您分配给它的值无论如何都会被覆盖。

UnityEngine.Object 其中GameObject派生自有一个隐式运算符 bool

Does the object exist?


而不是直接 == null比较你应该检查
public static bool IsNull<T>(this T myObject, string message = "") where T : UnityEngine.Object
{
    if(!myObject)
    {
        Debug.LogError("The object is null! " + message);
        return false;
    }

    return true;
}

对于适用于任何引用类型的通用方法,您可以例如使用类似的东西
public static bool IsNull<T>(this T myObject, string message = "") where T : class
{
    if (myObject is UnityEngine.Object obj)
    {
        if (!obj)
        {
            Debug.LogError("The object is null! " + message);
            return false;
        }
    }
    else
    {
        if (myObject == null)
        {
            Debug.LogError("The object is null! " + message);
            return false;
        }
    }

    return true;
}

关于c# - 检查是否在 Unity3D 2019.3.05f 中的检查器中分配了 GameObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60189192/

相关文章:

c# - 为什么 GetShortestDayName 返回的名称比预期的要短?

sql - Oracle,NULL但不为NULL

c# - Intelligencia UrlRewriter 强制小写 URL

c# - 如何在 WinForms 中强制用户使用管理员帐户

C# 可插拔工厂/静态初始化

c# - 什么是 `invalid token in class` 错误?

c# - 设置数组的长度属性

c# - 从顶点位置以编程方式创建 3D 棱镜

javascript - 如何遍历 JavaScript 对象并检查空值?

MySql 按多列排序,首先对 NULL 条目进行排序