简体   繁体   English

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

[英]Check if a GameObject has been assigned in the inspector in Unity3D 2019.3.05f

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.如何在 Unity3D 的检查器中检查 MonoBehaviour 的公共游戏对象是否已分配,因为 null (object==null)的比较失败。

Concrete Example:具体例子:

I am about to write a generic method for Unity3D, that can be called on any nullable object.我即将为 Unity3D 编写一个通用方法,该方法可以在任何可空对象上调用。 It checks if the object is null and if so it writes a Debug.LogError(customMessage) .它检查对象是否为空,如果是,则写入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:该方法可以在代码中的任何位置的任何可为空对象上调用,例如在这个简单的 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.但我现在的问题是,如果我没有在编辑器中签署“testObject”,我的测试将无法工作,因为 testObject 似乎不为空,但它也无法使用,因为它没有被分配。 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.为什么(myObject == null)是假的,而Debug.Log(testObject)给我null只要相应的对象没有在统一检查器中分配。

Edit/Solution: Thanks to the help from derHugo I ended up with this generic code snippet:编辑/解决方案:感谢 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 has a custom implementation of equality == operator (see Custom == operator, should we keep it? which often leads to confusion / unexpected behavior. Unity 有一个相等==运算符的自定义实现(请参阅自定义 == 运算符,我们应该保留它吗?这通常会导致混淆/意外行为。

Even if an UnityEngine.Object has a value equal to null it is sometimes not == null .即使UnityEngine.Object的值等于null它有时也不是== null Object rather still stores some meta data in it eg 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 . Object仍然在其中存储一些元数据,例如,您得到的是MissingReferenceException ,而不是通常的NullReferenceException因为 Unity 实现了一些自定义异常,这些异常通常包含更多关于为什么值等于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.是一个public字段,它会自动序列化,因此您分配给它的null值在序列化过程中无论如何都会被覆盖。


UnityEngine.Object which GameObject derives from has an implicit operator bool UnityEngine.ObjectGameObject从派生有一个隐式操作bool

Does the object exist?对象是否存在?

Instead of a direct == null comparison you should rather check for您应该检查,而不是直接== 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;
}

For a general method working for any reference type you could eg 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM