In C#, one error puts fear, confusion, and frustration into the heart of every developer, especially beginners: NullReferenceException.
It will look like this in your Unity console, and it will cause your game to not work.
In case that screenshot isn’t clear, it reads:
NullReferenceException. Object reference not set to an instance of an object MyScript.Start() (at Assets/MyScript.cs:11)
Null references are very confusing for beginners, and you’ll probably get them frequently when learning to use Unity. Once you understand why these errors occur and how to fix them, you will save yourself hours of frustration and confusion!
C# Types Crash Course
This is a very brief summary. I recommend reading up on these concepts, as they are important to understand well. Understanding the differences between value and reference types is crucial to programming in C# and similar languages.
The reason a null reference occurs is to do with reference variable types.
Unlike a value type (e.g. an int or float), which you can think of as storing its own value, a reference type stores a memory address that references some data elsewhere in memory.
Value types always have a value – e.g. an int’s default value will be zero unless you assign a different value, but reference types do not reference anything by default…they are empty…the C# word for empty is null.
Reference type variables are generally objects – for example you might have a class called Car in your project, and each car in your game is an instance of the Car class.
Many of Unity’s components are reference type objects, e.g.
SpriteRenderer spr; // this will be null because no 'address' is given to it to point/link to. I have declared the variable but not assigned anything to it
SpriteRenderer spr = new SpriteRenderer(); // this will create a new SpriteRenderer object in memory, and then put a reference to it in the spr variable. spr is not null - it contains a pointer to a SpriteRenderer object
Though it’s not directly relevant to this topic, it’s important to know that multiple variables can point to the same object in memory.
SpriteRenderer xyz = spr; // this will make the new variable xyz point to the SAME SpriteRenderer as the spr variable (i.e. they both now point to the same object in memory)
What is a Null Reference Exception?
A null reference exception is an error that occurs when you try to access the non-existant object that a null reference type variable is (not) pointing at.
As an analogy, let’s go back to the Car object. You may have some code like this:
var carColour = MyCar.Colour;
The above code is requesting that the Colour property of the object that MyCar points to be assigned to the new variable carColour. This code is correct, but will give a Null Reference Exception if the MyCar variable is null (i.e. it does not contain a reference to an actual Car object). The code is trying to get a property of a non-existent car.
Avoiding Null References
You need to ensure that you don’t try to access null objects. The main ways of doing this are:
- Making sure you always assign the objects when you are supposed to
- Putting ‘null checks’ in your code to avoid errors when things are null
In Unity, you generally keep program structure simple, using mostly discrete scripts. This means that generally you are likely to need to assign references to objects at the time they are created. This keeps it relatively easy – many objects can be assigned in the Awake() or Start() methods.
Whenever you add an object to a script, make sure you think about how that variable gets populated with a reference to an actual object.
The Unity Inspector
A lot of null reference errors in Unity, especially for beginners (but trust me nobody is immune) are caused by the way Unity lets you assign values in the Inspector window.
Any variable that is public or has the [SerializeField] attribute before it is visible in the Unity Inspector as a field you can put data into. In the case of reference types, you need to select or drag-and-drop an object of the correct type into this field to ensure it points to an object at runtime. This is effectively the same as writing some code in the Awake() method to point your variable to an object.
You can of course still assign these in code, but for the purposes of this example, let’s assume we aren’t doing that.
A null check is a best practice way of checking to make sure something is not null before trying to access it.
if(myCar != null) myCar.Colour = "blue"; // before assigning the colour, make sure myCar is not null
Null can actually be a valid or expected value. For example, when you raycast in Unity, getting a null value means the raycast didn’t hit anything, so you can first check that it isn’t null, and if it isn’t you can go ahead and do whatever you need to with the result.
It’s also good to check for null even if you think it shouldn’t be possible. If something is null that you think should never be null there may be a problem somewhere in your code.
Diagnosing the Error Message
Finally, I’ll show you how to solve any NullReferenceException error. Unfortunately, due to the way the compiler works (something I don’t myself understand beyond a very, very basic level) the compiler can’t actually tell you ‘hey, myCar is null – fix it, dude’. It just knows that something caused it to fail. But you can find out by following these steps:
Find the Object that is Null
Look at the error message and soo the script and line number at the end of the message. This is where the null reference was encountered.
Go to that line of code and look for any reference type variables (usually called ‘objects’). An integer or float can’t be null, so ignore those and other value type variables. If there is only one reference-type variable, then you know that’s the one that’s null, but if there are multiple, you may need to investigate.
There are two ways to find out which variable is null:
- Put a breakpoint at the line of code in question. This will pause the game when it gets to this line, and you are then able to hover the mouse over each variable to see its value. This requires you to setup your IDE (the program you write the code in like VS Code) to attach to your project while you play it. Adding a break point usually involves clicking to the left of a line of code, but check your IDE’s instructions.
- Use Debug.Log to print the value of all the variables to the console.
- Find Why it is Null
Now you should know which variable(s) is null. Now you need to find out why. This can be one of several things:
- You created the variable but never assigned an object to it
- Your object had a reference to an object, but that object was destroyed (remember, multiple variables could point to the same object)
- Somewhere in your code you set the variable back to null
- You created the variable for dragging an object in the Inspector but didn’t drag the value in
- The code that gave your variable its value set it to null (e.g. a Raycast came back null because nothing was hit).
- You tried to access the object before it had been assigned, e.g. you tried to acces it in Awake(), but assigned the value in Start()
Track back through your code to find the reason the value is null. The easiest things to check are whether you gave the variable an initial reference when it was first created (either in code, e.g. the Start() function, or via the Inspector.
- If your variable is allowed to be null, then use a null check to make sure you ignore it.
- If your variable is given its reference by a function, check that function to see why it is returning null.
- As a last resort you may need to look up every time the variable is referenced in the project and see when it is being assigned or set to null.
- NOTE: this is one of the many reasons it’s important to keep your variables private unless there is a very good reason to make them public. If a public variable is causing a null reference error, it could be getting accessed in multiple scripts and different times; if it’s a private variable, then you know that the error is in its own script, which makes debugging a lot easier.
Reference type variables are null by default because they point to an object in memory, and the reference type can be created without pointing it to an object.
NullReferenceException errors occur when your code tries to do something to the object your variable points to but your object is not pointing to anything (i.e. its reference is null/empty)
The error message will tell you what line of code the error was on, and from that information you can work out what object is null.
Either handle null as a valid possible value with a null check or fix your code to ensure the variable is not null.
It’s always wise to check for null.