What is a NullReferenceException?

What NullReferenceException errors are (and how to fix them) in Unity

An error involving a NullReferenceException is something that new developers often encounter when working on projects in Unity. These errors occur when attempting to access object variables, or members of object variables, when the variable itself is null.

Although the cause is simple, NullReferenceException errors can present themselves in many different ways. As a result, fixing them isn’t always as straightforward as following a standard series of steps. In this article, we will explore the various ways that a NullReferenceException can occur in Unity, as well as how to handle these various situations.

If you don’t prefer reading and wish for more visual aid, check out our video guide here.
But if you prefer reading, scroll down to check the rest of the article.

In this article, here’s what we will be going through:

  1. Why is it a NullReferenceException?
  2. How do they happen (and how do we fix them)?
  3. Not every variable can have a null reference
  4. Conclusion

1. Why is it a NullReferenceException?

A NullReferenceException is an error that happens when your code tries to access an object variable (also known as a reference variable) that doesn’t exist (i.e. the value of the variable is null). Do you see where the name comes from now?

Object variables are called reference variables because the data for the object is stored in a separate address from the variable itself in memory (i.e. RAM). Instead of containing the data, the object variable will instead contain the reference address of the actual object. In layman terms, this means that the variable points to the object instead of storing it, like how a mailing address points to a house.

Hence, it is possible for different variables to point to the same object, such that modifying one variable will affect the value of another. Below is a simple example that illustrates this:

GameObject a = new GameObject();
GameObject b = a;
b.name = "Awesome name";
print(a.name); // Gives "Awesome name"

Interested to find out more about reference variables? You can check out our article about reference and value types in programming. This is a concept that is not exclusive to C# or Unity programming, so you will see it a lot when you work on other programming languages as well.

2. How do they happen (and how do we fix them)?

In a nutshell, whenever you see a NullReferenceException, this means that some object variable in your code is null (i.e. empty) for some reason. Most commonly, you will find them in situations where you are…

a. Trying to access a method or property (of a null object)

Take the following example. It is a piece of code that can be attached to a GameObject to make it behave like a projectile, making it move rightwards the moment it spawns.

using UnityEngine;

public class Projectile : MonoBehaviour {
	Rigidbody2D rb;
	public float speed = 10f;

	void Update() {
		rb.velocity = transform.right * speed;
	}
}

This is how a GameObject with the script attached will behave:

If you attach it the script to any GameObject in your Scene, however, you will get a NullReferenceException in the highlighted line above. This is because the variable rb has never been assigned a value, so running rb.velocity is the same as running null.velocity.

To rectify this, we will have to ensure that rb is assigned before we try to access its properties. A simple way to do this for our script is to add the following:

using UnityEngine;

public class Projectile : MonoBehaviour {
	Rigidbody2D rb;
	public float speed = 10f;

	void Start() {
		rb = GetComponent<Rigidbody2D>();
	}

	void Update() {
		rb.velocity = transform.right * speed;
	}
}

Be aware that your GameObject will need to have a Rigidbody2D component for this to work. Otherwise, GetComponent<Rigidbody2D>() will return null and you will get a null reference error anyway.

Make sure that you have a Rigidbody component.
A Rigidbody2D component is required for this to work.

Some additional notes:

  • NullReferenceException errors can occur even if you try to access methods of null objects. For example, using rb.AddForce(transform.right * speed) in the above example will give the same error.
  • When accessing properties within properties, it is possible for any object in the chain of properties to be null. For example, Rigidbody2D objects have a sharedMaterial property, which may or may not be null. Hence, in a line like rb.sharedMaterial.bounciness, it is possible for either rb or sharedMaterial to be null, and either one being null will cause a NullReferenceException.


Article continues after the advertisement:


b. Accessing a destroyed object

Sometimes, it is possible for a NullReferenceException to occur even if you properly assign your variables before you use them. Consider the following example:

using UnityEngine;

public class Shooter : MonoBehaviour {

    public GameObject bulletPrefab; // Assigned in the Inspector.
    GameObject lastBullet;

    void Update() {
        // Spawn a bullet whenever you press space.
        if(Input.GetKeyDown(KeyCode.Space)) {
            lastBullet = Instantiate(bulletPrefab, transform.position, transform.rotation);
            Destroy(lastBullet, 2); // Destroy bullet after 2 seconds.
        }

        // Control will print the name of the lastBullet on the Console.
        if(Input.GetKeyDown(KeyCode.LeftControl)) {
            print(lastBullet.name);
        }
    }
}

This is a script that can be attached to a GameObject so that:

  • Space causes it to shoot the projectiles we made earlier, save a reference to the projectile, and destroy the new projectile after 2 seconds.
  • Ctrl causes it to print out the name of the last projectile we shot.
shooter

If you press Ctrl more than 2 seconds after shooting your last projectile, you will either get a NullReferenceException or its closely-related cousin, a MissingReferenceException.

console error

This is because although lastBullet points to an object, if the object it points to gets destroyed, then the lastBullet variable will also become null.

If you want to prevent error messages from happening in such a case, you can add a check to see if an object variable is null before using it:

using UnityEngine;

public class Shooter : MonoBehaviour {

    public GameObject bulletPrefab; // Assigned in the Inspector.
    GameObject lastBullet;

    void Update() {
        // Spawn a bullet whenever you press space.
        if(Input.GetKeyDown(KeyCode.Space)) {
            lastBullet = Instantiate(bulletPrefab, transform.position, transform.rotation);
            Destroy(lastBullet, 2); // Destroy bullet after 2 seconds.
        }

        // Control will print the name of the lastBullet on the Console.
        if(Input.GetKeyDown(KeyCode.LeftControl) && lastBullet != null) {
            print(lastBullet.name);
        }
    }
}

Article continues after the advertisement:


c. Using an unassigned public variable

Taking the example from (2) above, we can also get a closely-related cousin of the NullReferenceException (called the UnassignedReferenceException) if we try to fire a bullet with an unassigned bulletPrefab variable.

unassigned projectile

To fix these errors, the solution is simple: Make sure you assign all the public variables you plan to use! If you would like a failsafe in case you forget to assign them, you can include a check to see if the object variable you want to use is null:

using UnityEngine;

public class Shooter : MonoBehaviour {

    public GameObject bulletPrefab; // Assigned in the Inspector.
    GameObject lastBullet;

    void Update() {
        // Spawn a bullet whenever you press space.
        if(Input.GetKeyDown(KeyCode.Space) && bulletPrefab != null) {
            lastBullet = Instantiate(bulletPrefab, transform.position, transform.rotation);
            Destroy(lastBullet, 2); // Destroy bullet after 2 seconds.
        }

        // Control will print the name of the lastBullet on the Console.
        if(Input.GetKeyDown(KeyCode.LeftControl) && lastBullet != null) {
            print(lastBullet.name);
        }
    }
}

3. Not every variable can have a null reference

In Unity, primitives (such as int, float and bool) and structs are value types, not reference types. This means that variables belonging to these 2 categories are not objects and do not hold references. Hence, they cannot cause NullReferenceException errors.

For more information on what value types are, you can check out this article:

4. Conclusion

It’s important to note that variables of reference types need to be properly initialized and assigned valid object references to avoid NullReferenceException (and related) errors. By implementing defensive coding practices, performing null checks, and ensuring that you assign variables, you can mitigate the risk of encountering these errors.

Did we miss any potential cause (or fix) for NullReferenceException errors? Feel free to highlight it to us in the comments below.


Article continues after the advertisement:


Leave a Reply

Your email address will not be published. Required fields are marked *

Note: You can use Markdown to format your comments.

This site uses Akismet to reduce spam. Learn how your comment data is processed.