The is operator can be used to check if an object is castable to a particular type.
object something = "Hello!";
if(something is int)
{
Debug.Log("The 'something' variable contains an integer value.");
}
if(something is float)
{
Debug.Log("The 'something' variable contains a floating-point value.");
}
if(something is string)
{
Debug.Log("The 'something' variable contains a string object.");
}
You can also use the is operator to both check if an object is castable to a particular type, and if it is, then cast it and assign it into a new variable.
if(something is string text)
{
Debug.Log($"The 'something' variable contains the string \"{text}\".");
}
You can also use the is operator to test if something is null or not.
object maybeSomething = null;
if(maybeSomething is null)
{
Debug.Log("The 'maybeSomething' variable does not contain any object.");
}
if(maybeSomething is not null)
{
Debug.Log("The 'maybeSomething' variable does contain some object.");
}
The == operator on the other hand can be used to test if an object is equal to another object (not a type, but an instance of a type).
One special property of the == operator is that any class can override it with a custom implementation.
For example the String class overrides it, so that it returns true for two strings if their character arrays have identical contents, even if they actually refer to different objects in memory.
string a = new String("Hello!");
string b = new String("Hello!");
if(a == b)
{
Debug.Log("The 'a' and 'b' variables both contain the same string value.");
}
However, the overloaded == operator will not get used if the instance is contained in a variable of a base type or an interface type.
object a = new String("Hello!");
object b = new String("Hello!");
if(a == b) // uses the == operator in the object class, not the overloaded == operator in the string class
{
Debug.Log("The 'a' and 'b' variables both contain the same string value."); // not executed
}
This is important to know when dealing with UnityEngine.Object-derived classes (components, game objects, scriptable objects etc.). The == operator in the Object class has been overloaded to return true when a destroyed Object is compared against a null value. But if a destroyed Object is stored inside an interface type variable, or an object type variable, then comparing it against null returns false instead.
Player player = GetComponent<Player>();
Destroy(player);
if(player == null)
{
Debug.Log("player == null"); // this gets printed
}
if(player is IPlayer iplayer)
{
if(iplayer != null) // does not use the overloaded == operator in the UnityEngine.Object class
{
Debug.Log("iplayer != null."); // this also gets printed
}
}
And since the is operator can not be overridden, it has not been possible for Unity to make it return true for destroyed Objects.
Player player = GetComponent<Player>();
Destroy(player);
if(player is not null)
{
Debug.Log("player is not null"); // this also gets printed
}