Game Dev Cheat Sheet

Runtime exceptions

NullReferenceException: Object reference not set to an instance of an object

The exact message

NullReferenceException: Object reference not set to an instance of an object
Variants of this message
  • Object reference not set to an instance of an object
  • NullReferenceException: Object reference not set to an instance of an object.
  • System.NullReferenceException: Object reference not set to an instance of an object

What it means

You tried to use a variable that holds nothing. The message is not telling you which variable, only that one of the references on the failing line was null when you reached it. Unity reports the file and line number in the stack trace, so this is one of the more tractable errors once you know how to read it: the line is given to you, and the work is identifying which of the references on that line is empty.

Causes and fixes

Ranked by how often they actually occur, most common first.

  1. An Inspector field was never assigned

    A public or [SerializeField] field that you intended to drag a reference into in the Inspector defaults to null when left empty. This is the single most common cause in practice, and it is especially easy to hit after adding a field to a script that is already on several prefabs, because existing instances keep the empty value.

    The fix: Select the component in the Inspector and check every object field for None. Where a field must always be set, assigning it in code from Awake, or marking the requirement in the Inspector, is more reliable than remembering to drag it.

    Fail loudly at startup with the object named, rather than at some later frame with no context.

    using UnityEngine;
    
    public class Turret : MonoBehaviour
    {
        [SerializeField] private Transform muzzle;
        [SerializeField] private ParticleSystem muzzleFlash;
    
        void Awake()
        {
            if (muzzle == null)
            {
                // Passing "this" makes clicking the console entry select the
                // offending object in the Hierarchy.
                Debug.LogError($"{name}: muzzle is not assigned.", this);
                enabled = false;
            }
        }
    }

    Source: Unity Manual: Null references

  2. GetComponent found nothing and returned null

    GetComponent returns null rather than throwing when the component is not on the GameObject. Chaining straight off the call, as in GetComponent<Rigidbody>().velocity, turns that null into an exception on the same line. The usual causes are the component sitting on a child or parent rather than the object itself, or being added later at runtime.

    The fix: Use TryGetComponent, which returns a bool and avoids allocating in the failure case, or store the result and test it before use. Where the component is genuinely required, [RequireComponent] makes Unity add it automatically and prevents its removal.

    TryGetComponent is the modern form and reads better than a null check.

    using UnityEngine;
    
    [RequireComponent(typeof(Rigidbody))]
    public class Launcher : MonoBehaviour
    {
        void Start()
        {
            // Preferred: no allocation on failure, and the intent is explicit.
            if (TryGetComponent(out Rigidbody body))
            {
                body.linearVelocity = Vector3.up * 5f;
            }
    
            // Searching children or parents is a different call, and a common
            // reason GetComponent "inexplicably" returns null.
            Collider childCollider = GetComponentInChildren<Collider>();
        }
    }

    Source: Unity Scripting API: Component.TryGetComponent

  3. GameObject.Find or a similar lookup did not match

    GameObject.Find, transform.Find and GameObject.FindWithTag all return null when nothing matches. Find is case sensitive and matches the full name, so a trailing space or a renamed object breaks it silently. It also ignores inactive GameObjects, which is why a lookup that worked yesterday fails once an object starts disabled.

    The fix: Test the result before using it. Better, avoid name-based lookups altogether: a serialised reference set in the Inspector cannot be broken by a rename, and it is considerably faster than searching the scene.

    Source: Unity Manual: Null references, failed object searches, Unity Scripting API: GameObject.Find

  4. The reference is used before Awake or Start has run

    Fields assigned in Awake are not available to another script's Awake, because the order in which Unity calls Awake across different components is not defined unless you set it explicitly. A script reading another component's field from its own Awake therefore sometimes works and sometimes does not, which makes this the most confusing version of the error.

    The fix: Assign your own references in Awake and read other components' references in Start, which always runs after every Awake. Where two scripts genuinely must initialise in a fixed order, set it in Project Settings > Script Execution Order rather than relying on chance.

    Source: Unity Manual: Order of execution for event functions

  5. An element of a collection or array is null

    A List or array sized in the Inspector fills its new slots with null. Iterating it and calling a member on each element throws on the first empty slot. The stack trace points at the loop body rather than at the Inspector, so the cause looks unrelated to where it is reported.

    The fix: Skip null entries when iterating, and treat an unexpected null as a data problem worth logging rather than silently continuing. Where the collection should never contain gaps, validate it in OnValidate so the problem surfaces while editing rather than at runtime.

    OnValidate runs in the Editor whenever the component changes.

    using UnityEngine;
    
    public class WaypointRoute : MonoBehaviour
    {
        [SerializeField] private Transform[] waypoints;
    
    #if UNITY_EDITOR
        void OnValidate()
        {
            if (waypoints == null) return;
    
            for (int i = 0; i < waypoints.Length; i++)
            {
                if (waypoints[i] == null)
                {
                    Debug.LogWarning($"{name}: waypoint {i} is empty.", this);
                }
            }
        }
    #endif
    }

    Source: Unity Scripting API: MonoBehaviour.OnValidate

How to prevent it

Read the stack trace before changing any code. The first line names the file and the line number, and double-clicking the console entry opens it. Everything below that line is the call chain that led there, which tells you which caller passed the empty value.

Where a line chains several members together, split it up while debugging. A single line such as target.GetComponent<Health>().Current has three places a null can hide, and splitting it tells you which one in a single run.

Prefer serialised references over runtime lookups. A field you drag in the Inspector is checked when the scene loads and cannot be broken by renaming an object, whereas GameObject.Find fails silently and only at the moment it runs.

Validate required references in Awake and disable the component when one is missing. One clear error naming the object beats a stream of exceptions every frame from a component that cannot work.

Unity version differences

Behaviour is unchanged across supported Unity versions. Note that Rigidbody.velocity was renamed to Rigidbody.linearVelocity in Unity 6; the code above uses the current name.

Sources

Frequently asked questions

How do I find which variable is null?
The stack trace gives you the file and the line. If that line touches more than one reference, split it into separate statements and run again: the exception then points at the specific step that failed. Adding Debug.Log calls that print each reference just before the failing line works too, and printing the object rather than a message tells you whether it is null or merely wrong.
What is the difference between NullReferenceException, UnassignedReferenceException and MissingReferenceException?
They describe three different situations. UnassignedReferenceException means a serialised field was never filled in the Inspector. MissingReferenceException means the object existed and has since been destroyed. NullReferenceException is the general case: a reference that is null for any other reason, such as a lookup that found nothing or a field never assigned in code. Unity throws the more specific two where it can, precisely because they point at different fixes.
Should I just wrap everything in null checks?
No. A null check that hides the problem turns a loud failure into a silent one, and the bug then surfaces somewhere less obvious. Check where null is a legitimate state, such as an optional target that may not exist yet. Where the reference is required, let it fail, or fail deliberately with a logged error that names the object.
Why does it work in the Editor but throw in a build?
Usually because something the Editor provides is absent in a player. Code inside #if UNITY_EDITOR is compiled out, so a reference initialised there is null in a build. Editor-only APIs behave the same way. Scene loading order and script execution order can also differ enough to expose an initialisation race that the Editor happened to win.
Does a null check cost performance?
Comparing a UnityEngine.Object to null is slightly more expensive than an ordinary C# null check, because Unity overloads the operator to also ask whether the underlying native object has been destroyed. The cost is small and irrelevant outside a tight loop running every frame. Caching the result of a check rather than repeating it per frame handles the rare case where it matters.

Last updated: