Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetComponent returning "null" instead of null

I'm confused about the return value of GetComponent if the requested component is not attached to the object. According to the Unity documentation, GetComponent should return null. However, what appears to be happening is that GetComponent is returning a "null" object of the requested type, rather than the value null.

In this example, my game object does not have a CircleCollider2D attached to it. When I set a breakpoint on the line CircleCollider2D x = GetComponent<CircleCollider2D>();, I get this result

Why is the returned value not null?

EDIT:

Here's a full screenshot of the code and the values in the debugger.

ANOTHER EDIT:

Could it be that Unity has overloaded the == operator so that GetComponent always returns a object, but the object can have an internal "null" state which returns true when compared to null? I can see the following declarations in the UnityEngine namespace

public static bool operator ==(Object x, Object y);
public static bool operator !=(Object x, Object y);
like image 991
Ben Rubin Avatar asked Nov 07 '25 21:11

Ben Rubin


1 Answers

It seems like GetComponent<T>() doesnt return TRUE null. Instead it returns new T with default values that fires MissingComponentException when using any null field. GetInstanceID() and GetHashCode() work because they only use int m_InstanceID which is set to default 0. Not sure how ToString() works but it probably returns "null" when m_InstanceID == 0.

Proof:

void Start()
    {
        CircleCollider2D getComponent = GetComponent<CircleCollider2D>();
        CircleCollider2D empty = null;
        CircleCollider2D newCC = new CircleCollider2D();
        Debug.LogFormat("getComponent.GetInstanceID() {0}", getComponent.GetInstanceID());
        Debug.LogFormat("newCC.GetInstanceID() {0}", newCC.GetInstanceID());
        try
        {
            Debug.LogFormat("empty.GetInstanceID() {0}", empty.GetInstanceID());
        }
        catch (System.NullReferenceException e)
        {
            Debug.Log("empty.GetInstanceID() doesnt work, im true null");
        }
        try
        {
            string t = getComponent.name;
        }
        catch (System.Exception e)
        {
            Debug.Log(string.Format("getComponent fires {0} when any field is null", 
                e.ToString()));
        }
        try
        {
            string t = newCC.name;
        }
        catch (System.Exception e)
        {
            Debug.Log(string.Format("newCC fires {0} when any field is null",
                e.ToString()));
        }
    }

Results:

getComponent.GetInstanceID() 0
newCC.GetInstanceID() 0
empty.GetInstanceID() doesnt work, im true null
getComponent fires UnityEngine.MissingComponentException
newCC fires System.NullReferenceException

Also:

getComponent.GetHashCode() = 0
getComponent.ToString() = "null"

Why getComponent == null is true? Usually it's just:

`getComponent.GetInstanceID() == otherComponent.GetInstanceID()`

In o == null case it's:

return !(
o.GetCachedPtr() != IntPtr.Zero || (!(o is MonoBehaviour) && 
!(o is ScriptableObject) &&
Object.DoesObjectWithInstanceIDExist(o.GetInstanceID())));

So i guess object with InstanceID = 0 never exists. Search for decompiled UnityEngine/UnityEngine/Object.cs if u want to know more.

like image 149
kamyker Avatar answered Nov 10 '25 12:11

kamyker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!