0

I found a way to get around this issue in the code, but I would like to understand why this is happening because I want to learn C# well. I´ve searched a lot and could simplify the problem, here's the simplified code:

/*MyCustomComponent.cs, this is attached to a game object in the scene*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MyCustomComponent : MonoBehaviour {
    void Start () {
        Test testInstance = new Test();
        Debug.Log (testInstance);
        Debug.Log (testInstance == null);
        Debug.Log (testInstance.Equals(null)); //Also tried the same with Equals()
        Debug.Log (testInstance.value);
    }
}

/*Test.cs*/
using UnityEngine;
using System.Collections;

public class Test : Object {
    public int value = 7;
    public Test(){

    }
}

Console Output:

null
true
7

Why is this happening? How can be possible an Object is null but returns a property value?

6
  • The output returns: null, true, true, 7. (I had the Equals() line commented out, so when I wrote it here I forgot to write the second true value). Commented Mar 1, 2018 at 13:40
  • 1
    You inherit your class from Object, your variable object is null, but class parameters exist. Remove Object from inheritance Commented Mar 1, 2018 at 13:46
  • 1
    In this context, it's important to note that UnityEngine.Object is not System.Object. The latter is the ultimate ancestor of all classes in C# , the former has its own behavior. Commented Mar 1, 2018 at 13:52
  • @MarkBenovsky I think that should be an answer... Commented Mar 1, 2018 at 14:34
  • Thank you very much for your answer (that worked!). If I remove the ": Object" from Test.cs, it returns: Test (or false if the condition tries to see if it´s null). Anyway, I still don´t get why when I do testInstance = new UnityEngine.Object(); // or: new System.Object(); It returns null instead of Object. (it also returns true when the condition ask if its equal to null) Commented Mar 1, 2018 at 15:13

1 Answer 1

1

Because Unity.Object works in a very peculiar way, basically it contains data regarding the managed object while pointing to the native object (crudely speaking).

Let's make an example: you create a new object inheriting from MonoBehaviour. Now you have two objects, one on the native side and one on the managed side. You can access the instanceID propriety of the managed object thanks to the fact that MonoBehaviour inherits from Unity.Object. Basically, the latter is used to show all the relative data of the object in the Inspector.

Now, you want to Destroy this game object by calling the same named method. The native object is actually destroyed, but the managed object is not, since all managed objects can only be destroyed by the garbage collector. It's at this point that Unity.Object becomes null: it's a trick of the Unity engine uses in order to avoid that you try to access a native object which doesn't exist anymore. Eventually, when the GC is called, this Unity.Object will be destroyed too.

And this is why you should never create an Unity object which inherits directly from Unity.Object, but only from MonoBehaviour or ScriptableObject.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, I read all the replies again and also the UnityEngine.Object() and System.Object() documentation, and it's clear now. =) My mistake was that I was trying to inherit from System.Object but I was using "Object" (which is UnityEngine.Object).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.