Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

(bool) gameObject vs gameObject == null?

Discussion in 'Scripting' started by Deleted User, Dec 31, 2017.

  1. Deleted User

    Deleted User

    Guest

    What is the difference between:

    Code (CSharp):
    1. var go = GameObject.Find("random name");
    2. if (go) go.SetActive(false);
    And

    Code (CSharp):
    1. var go = GameObject.Find("random name");
    2. if (go != null) go.SetActive(false);
     
    Last edited by a moderator: Jan 1, 2018
  2. AcePilot10

    AcePilot10

    Joined:
    Aug 11, 2016
    Posts:
    34
    gameObject is a reference to the GameObject of whatever your working with (Transform, MonoBehaviour). Saying
    Code (CSharp):
    1. if(someComponent.gameObject != null) {
    is seeing if the referenced GameObject exists. Although, if the gameObject doesn't exist, I would imagine the 'someComponent' component stated above would throw a Null exception before anything else.
     
  3. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    null translates to false, so essentially they are the same. I hadn't seen it used that way to test for a null before. It might work with GameObject because of a return or something, but I think I would just test for null to be on the safe side, unless someone knows if that would always be safe to use for any object.
     
    Last edited: Dec 31, 2017
  4. Deleted User

    Deleted User

    Guest

    Sorry if I wasn't clear. I meant what is the difference between:

    Code (CSharp):
    1. var go = GameObject.Find("random name");
    2. if (go) go.SetActive(false);
    And

    Code (CSharp):
    1. var go = GameObject.Find("random name");
    2. if (go != null) go.SetActive(false);
     
  5. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,924
    Is this about the Unity overloads? In Unity, "if(go==null)" doesn't actually check whether it's null. If "go" isn't null, the system also checks whether the gameObject it points to has been destroyed, which also counts as null.

    I think there may have once been a difference, in Unity, between "if(go)" and "if(go==null)" (the first didn't use the good Unity trick?) But I did a little testing and couldn't find a difference. They did discuss keeping/changing it recently.
     
    phobos2077 and (deleted member) like this.
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    David_Knopp and UziMonkey like this.
  7. UziMonkey

    UziMonkey

    Joined:
    Nov 7, 2012
    Posts:
    206
    This is correct. To expand on it, C# will try to convert any expression in an if statement to boolean. In this case, it's given an implicit conversion from Object (from which GameObject, MonoBehaviour, etc all inherit from) to boolean. In particular, this specific line. It's just comparing to null using the CompareBaseObjects method.

    If you look up slightly you'll see that the Equals method also uses this CompareBaseObjects method to do its comparison. I'm sure there may be some subtle differences, but more or less both if statements are doing the same exact thing. They'll be true if the reference is not null and references a valid Unity object, otherwise it'll be false.

    Which one to use? I'd use the more explicit one. It's a few extra characters and is more clear.

    There's one more thing to understand here: even though the references are not null, references to Unity objects that have been destroyed will appear to be null. If you destroy a GameObject and then compare a reference you had to it before destroying with null, it will appear to be null. It's not though, and this can cause some confusion. If you store a reference to a MonoBehaviour on an object then destroy that object, you can still call methods on that "dead" behaviour and it can appear to continue working. Just know that sometimes you can have "zombie" objects that when compared with null will appear to be null, but some methods on them will still work with no errors.
     
  8. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    Last edited: Jan 1, 2018
  9. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Destroyed objects equating to null is what I have a problem with. Because you can destroy game objects indirectly way too easily. Basically another level of indirection that just makes it more difficult to write proper code around. It's too easy to just destroy a GameObject with multiple components or children with components, leaving references in other areas of the code invalid. You really need a pattern where you explicitly assign a GameObject to a class, and it's only through that class that you can destroy it, along with that class knowing about any other components on the GameObject and children.

    Which means using stuff like GameObject.Find is out of the question for the most part, outside of cases like networked games where you don't have a choice.
     
  10. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    You can code your own (generic C#) class to use an implicit bool operator for the same purpose. That's what they did.

    Edit:
    After I actually read the post, I see that's said there, too. So not "automatic" but also part of the language, and not just Unity..

    Read the first bit of the link you posted, and it goes on to say in the first comment something I would have said, too. In C, if(pointer) means not null. They also have if(1) or if(someInt), which I miss, but that is unrelated, just babbling lol. Related, though, as it was basically if !Zero :)
     
    Last edited: Jan 1, 2018