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

…衆ロ難τιáo~ 提交于 2021-01-12 05:09:42

问题


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

回答1:


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


来源:https://stackoverflow.com/questions/60189192/check-if-a-gameobject-has-been-assigned-in-the-inspector-in-unity3d-2019-3-05f

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!