Unity's Null
Part of the Unity Scripting Basics section of Coddy's Unity journey. Lesson 60 of 85.
A Unity object has two halves: the C# object your script holds, and the engine object behind it. Destroy(obj) removes the engine half at the end of the frame, but your variable still points at the C# half, so in plain C# terms it is not null. Unity overrides == to cover this: once the object is destroyed, obj == null is true, and so is the short test !obj. This is Unity's fake null.
?., ?? and is null do not use that ==. They test the C# reference, which still exists, so they let the call through, and touching the destroyed object throws MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it. This label shows the name of the race leader, who can be knocked out (destroyed):
[SerializeField] private Transform leader;
void Update()
{
// throws once the leader is destroyed: string shown = leader?.name ?? "nobody";
string shown = leader != null ? leader.name : "nobody";
Debug.Log("Leader: " + shown);
}For anything that comes from UnityEngine.Object (GameObjects, components, your scripts), test with == null, != null or if (obj), and keep ?. and ?? for plain C# objects such as strings. Also remember that Destroy waits for the end of the frame: until then, the object is still alive and == null is false.
Challenge
MediumStop the drone's errors once its target is destroyed.
- In
Update(), replace both lines withif (target != null), Unity's own null test. - Inside it, write
transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);.
Press Play: the drone chases the target, then waits with no errors in the Console. Then Check.
Try it yourself
using UnityEngine;
public class Chaser : MonoBehaviour
{
[SerializeField] private Transform target;
[SerializeField] private float speed = 2f;
void Start()
{
Destroy(target.gameObject, 2f); // the target is destroyed after 2 seconds
}
void Update()
{
Vector3 goal = target?.position ?? transform.position;
transform.position = Vector3.MoveTowards(transform.position, goal, speed * Time.deltaTime);
}
}
All lessons in Unity Scripting Basics
1C# Basics in Unity
Hello, UnityVariablesDecimals Need an fText in the ConsoleVariables That RememberIf and ElseCompare NumbersRecap: Coin Collector2Make It Move
Place the CubeMove Every FrameTurn Every SecondSteer with the KeysRecap: Drive the Cube5Vectors
Adding VectorsDirectionsLocal and World SpaceDiagonal SpeedDistance Between ThingsVector3 Is a StructRecap: Drone Pilot8GameObjects and Components
References in the InspectorGet a ComponentMissing ComponentsAdd a ComponentRequireComponentShow and HideRecap: Light Switch6Transforms and Hierarchy
Parents and ChildrenHoist the FlagScaleLook At ThingsMove Toward a PointRecap: Orbiting Moon9Project: Catch the Star
The CatcherA Falling StarPractice on your own: Unity playground