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. Dismiss Notice

Object is null, but I can access a property without a Null Reference Exception

Discussion in 'Scripting' started by mattbrand, Nov 1, 2016.

  1. mattbrand

    mattbrand

    Joined:
    Jan 16, 2011
    Posts:
    98
    I have a really weird thing happening that I can't figure out. I set a variable _redTeam.AttackMVP, but then when I check the results, the AttackMVP.Name is accessible and correct, but the AttackMVP itself is null.

    This code:
    Code (csharp):
    1.  if(piece.ID==redAttackMVP)
    2. {
    3. _redTeam.AttackMVP=piece;
    4. Debug.Log("piece="+_redTeam.AttackMVP);
    5. Debug.Log("setredattackmvp="+_redTeam.AttackMVP.Name);
    6. }
    Yields this result in the log:
    "piece = null"
    "set red attack mvp = venonat"

    How is this possible?
     
  2. namwenio

    namwenio

    Joined:
    Nov 1, 2016
    Posts:
    1
    Is the AttackMVP class derived from a Monobehavior?
    Can you post the class definition.
     
  3. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    It could just be that Debug.Log has no way to print out a string value for whatever class Piece and AttackMVP are, especially if they aren't derived from MonoBehaviour
     
  4. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    452
  5. mattbrand

    mattbrand

    Joined:
    Jan 16, 2011
    Posts:
    98
    AttackMVP is an instance of the class Piece, which inherits from MonoBehaviour.
    Code (CSharp):
    1. public class Piece : MonoBehaviour
    @kru - that is very interesting, had never seen it before. So it seems in this case, it is because the GameObject gets destroyed, but the class data remains intact. So the null check returns true, because it's using the "fake null" check. While the class data is actually there.
     
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,840
    That's it exactly. You have kicked over a stone and discovered a bit of very dark (yet darned convenient) magic in the Unity environment. Now that you know about it, you can safely put it to use.
     
  7. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,181
    Just be aware that this method:

    Code (csharp):
    1. ==
    is static. This means that if you've got two UnityEngine.Objects that you're comparing with ==, but you've referenced them through System.Object or (more likely!) some interface, the magic null check will not happen, as the call will dispatch to System.Object.== instead of UnityEngine.Object.==

    Example:

    Code (csharp):
    1. IEnumerator Start() {
    2.     GameObject go1 = new GameObject();
    3.  
    4.     object o1 = go1;
    5.  
    6.     Debug.Log(go1 == null); //false
    7.     Debug.Log(o1 == null); //false
    8.  
    9.     yield return null; //wait a frame
    10.  
    11.     Destroy(go1);
    12.  
    13.     //Destroy happens end-of-frame, so wait another!
    14.     yield return null;
    15.  
    16.     Debug.Log(go1 == null); //true
    17.     Debug.Log(o1 == null); //false!
    18. }
     
    JoshuaMcKenzie likes this.
  8. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    817
    Does your piece class overwrite ToString?