Here's a null gotcha I just got stung by, I hope this helps someone else! Code (csharp): Object o = new Object(); print( o ); // "null" print( o == null ); // True print( ReferenceEquals( o, null ) ); // False print( (System.Object)o == null ); // False Transform t = transform.Find( "DoesntExist" ); print( t ); // "null" print( t == null ); // True print( ReferenceEquals( t, null ) ); // False print( (System.Object)t == null ); // False So UnityEngine.Object overrides override ToString and Equals to try to pretend to be null when it isn't. This makes for some pretty confusing debugging and unexpected behaviour in functions like: Code (csharp): void CheckNotNull( object o ) { if( o==null ) throw new Exception("barf"); } Personally, I think returning "null" from ToString() and returning true to equality with null is just asking for trouble. Now I've just got to make my sanity checking classes behave sanely .
So here are ways you should and should not check any Unity object for null. Of course you can simply use obj==null if the reference hasn't been passed into any generic functions or it hasn't been cast to a non-unity type. Doesn't work, uses System.Object.Equals() Code (csharp): public static bool IsNull( object obj ) { return obj == null; } Surprisingly this doesn't work either Code (csharp): public static bool IsNull<T>( T obj ) { return obj == null; } This does work, but adds a dependency to Unity. Can't use it for non Unity objects. Code (csharp): public static bool IsNull<T>( T obj ) where T : UnityEngine.Object { return obj == null; } Amusingly this works, but obviously not for objects that are actually null. Code (csharp): public static bool IsNull<T>( T obj ) { return obj.Equals(null); } Almost equally (no pun) amusing is that this verbose line is the correct answer. This is the only way I know of checking whether a reference to a non-unity object or generic type is null or is a Unity object is pretending to be null. Code (csharp): public static bool IsNull<T>( T obj ) { return EqualityComparer<T>.Default.Equals(obj,default(T)); } My sanity checking library is now sane again.
That's interesting; glad I saw this before I ran into the issue, that would have been some confusing debugging.
Since we have already crosslinked this question to this thread here i link back and post a working null check for any kind of reference in a unity application. Code (csharp): public static bool IsNull(System.Object aObj) { return aObj == null || aObj.Equals(null); } The idea is simple, any "normal" null-reference will be handled by the first condition. Unity's fake-null-objects aren't actually null so the System.Object == operator returns false. In this case we additionally check the Equals function which is an instance function an will return true.
We have just taken a look at a bug submitted related to this issue. As mentioned here, this behavior is by design, but still rather odd. See the related discussion on the forum here for more details: http://forum.unity3d.com/threads/null-check-inconsistency-c.220649/
Old thread but one of the first problems I ran into using Unityscript. I specifically wanted to compare to null using pragma strict. My solution was kindergarten quality but it worked: declare an "empty variable" to compare: Code (JavaScript): #pragma strict public var myGameObj: GameObject; private var emptyGO: GameObject; start(){ if (myGameObj != EmptyGO){ //do something } else{ //cry foul } }[code]
I feel like I'm going mad. Does unity simply PRETEND that an object is null when it's actually still instantiated? In the code below I have an example where I am able to get a value out of a property from an object that is supposed to be null. Any advice? Code (CSharp): if(myGameObj == null) { //Special null case Debug.Log(myGameObj.MaxHealth); //prints out 100 somehow... Debug.Log(myGameObj); //prints null Debug.Log(myGameObj.name); //Gives a MissingReferenceException error } else { //Do stuff with game object }
The best explanation is in this blog post. The answer to the question the blog post asked seems to have been "yes, at least for now". From the last time somebody mentioned this:
Upper Posts does not work for my case. i solved it in this way; Code (CSharp): using UnityEngine; public class NullSolving:MonoBehaviour { private byte FieldForTestAccess=0; //or any field ,not especially fo test. void Start(){} void Update(){} public static bool isNull(NullSolving nullSolving){ try{ byte CheckAccess= nullSolving.FieldForTestAccess ; // if object is null thrown Exeption return false; }catch { return true; } } }
That is a pretty slow way of checking for null. When an exception is thrown, the entire stack is unwound, which is a very, very slow process. It's brutal on mobiles and consoles. You should just be able to do Code (csharp): bool IsReallyNull(System.Object obj) { return System.Object.ReferenceEquals(obj, null); } and get the same results with a faster speed.