检查是否在 Unity3D 2019.3.05f 中的检查器中分配了 GameObject [英] Check if a GameObject has been assigned in the inspector in Unity3D 2019.3.05f

查看:27
本文介绍了检查是否在 Unity3D 2019.3.05f 中的检查器中分配了 GameObject的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:

<块引用>

如何在检查器中检查 MonoBehaviour 的公共游戏对象是否已分配Unity3D,因为 null (object==null) 的比较失败.

具体例子:

我即将为 Unity3D 编写一个通用方法,该方法可以在任何可空对象上调用.它检查对象是否为空,如果是,则写入 Debug.LogError(customMessage).该方法如下所示:

 public static bool IsNull([CanBeNull] this T myObject, string message = ""){如果(myObject!= null)返回false;Debug.LogError("对象为空!" + message);返回真;}

可以在代码中的任何位置的任何可为空对象上调用该方法,例如在这个简单的 Monobehaviour 中:

公共类 TestScript : MonoBehaviour{公共游戏对象 testObject = null;公共无效测试对象(){var result = testObject.IsNull("错误信息");调试日志(结果);Debug.Log(testObject);}}

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

<块引用>

错误

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

编辑/解决方案:感谢 derHugo 的帮助,我最终得到了这个通用代码片段:

 public static bool IsNull(this T myObject, string message = "") where T : class{开关(我的对象){案例 UnityEngine.Object obj 当 !obj:Debug.LogError("对象为空!" + message);返回真;情况为空:Debug.LogError("对象为空!" + message);返回真;默认:返回假;}}

解决方案

Unity 有一个对等式 == 运算符的自定义实现(参见 自定义 == 运算符,我们应该保留它吗?这通常会导致混淆/意外行为.>

即使 UnityEngine.Object 的值 等于 null 它有时也不是 == null.Object 而是仍然在其中存储一些元数据,例如你会得到一个 MissingReferenceException,而不是通常的 NullReferenceException,因为 Unity 实现了一些自定义异常,这些异常通常包含更多关于为什么值等于 null.

特别是因为

public GameObject testObject = null;

是一个 public 字段,它会自动序列化,因此您分配给它的 null 值将在序列化过程中无论如何都会被覆盖.


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

<块引用>

对象是否存在?

你应该检查而不是直接的 == null 比较

public static bool IsNull(this T myObject, string message = "") where T : UnityEngine.Object{如果(!myObject){Debug.LogError("对象为空!" + message);返回假;}返回真;}


对于适用于任何引用类型的通用方法,您可以例如使用类似

public static bool IsNull(this T myObject, string message = "") where T : class{if (myObject 是 UnityEngine.Object obj){如果(!对象){Debug.LogError("对象为空!" + message);返回假;}}别的{如果(我的对象 == 空){Debug.LogError("对象为空!" + message);返回假;}}返回真;}

Question:

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.

Concrete Example:

I am about to write a generic method for Unity3D, that can be called on any nullable object. It checks if the object is null and if so it writes a Debug.LogError(customMessage). The Method looks like as follows:

 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;
 }

The method can be called on any nullable object, anywhere in the code, for example within this simple Monobehaviour:

public class TestScript : MonoBehaviour
{
    public GameObject testObject = null;

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

For most use cases my method works perfectly and saves a lot of time during encoding/debugging. But my problem now is that if I haven't signed the "testObject" in the editor, my test won't work because the testObject seems to be not null, but it's also not usable because it's not assigned. In this case, the console output is:

False
null

How comes that (myObject == null) is false, while the Debug.Log(testObject) gives me null as long as the corresponding object has not been asigned in the unity inspector.

Edit/Solution: Thanks to the help from derHugo I ended up with this generic code snippet:

 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 has a custom implementation of equality == operator (see Custom == operator, should we keep it? which often leads to confusion / unexpected behavior.

Even if an UnityEngine.Object has a value equal to null it is sometimes not == null. Object rather still stores some meta data in it e.g. you get a MissingReferenceException, not a usual NullReferenceException because Unity implemented some custom exceptions that often hold more detail to why the value is equal to null.

Especially since

public GameObject testObject = null;

is a public field it is automatically serialized and thus the null value you assigned to it will be overwritten anyway during the serialization.


UnityEngine.Object which GameObject derives from has an implicit operator bool

Does the object exist?

Instead of a direct == null comparison you should rather check for

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;
}


For a general method working for any reference type you could e.g. use something like

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;
}

这篇关于检查是否在 Unity3D 2019.3.05f 中的检查器中分配了 GameObject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆