Here’s a null gotcha I just got stung by, I hope this helps someone else!
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:
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 :).
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.
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.
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.
public static bool IsNull<T>( T obj )
{
return EqualityComparer<T>.Default.Equals(obj,default(T));
}
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.
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:
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:
#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?
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
}
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 dobool IsReallyNull(System.Object obj) { return System.Object.ReferenceEquals(obj, null); } and get the same results with a faster speed.