Understanding null reference exceptions in Unity is essential for any successful Unity developer. Failure to comprehend this can result in poorly written code and a frequently crashing game. Crashes are not something you should risk in your game build, as they can lead to frustrated players, high user churn, and a subsequent loss of revenue. The proper knowledge of null in Unity can alleviate stress in the process of game development, free up more time for innovation, and produce a successful mobile game.

In this blog post, we’ll answer the following questions:

  • What is null in Unity?
  • What are the key ways to prevent null reference exceptions in your Unity games?
  • How can you solve null reference exceptions?

What is null in Unity?

In Unity, null is a value that shows that an object or component in the game doesn’t refer to anything in the game’s memory. While null in Unity is similar to null in other programming languages in that it does represent the absence of an object, it’s different in a key way.

Improper understanding of how Unity treats null can cause a hard to debug NullReferenceException. This exception is a runtime error that happens when the code attempts to access an object or component that is null. This NullReferenceException can occur if a variable isn’t initialized or if a GameObject or component is destroyed or not found in the scene.

This can differ from expectations because Unity overrides the == operator. Unity provides their own definition for the == operator. This has precedence over the standard == operator and can create unexpected behavior. When you write code like gameObject == null, that code checks if the C# wrapper object is null or the backing C++ object has been destroyed. However, for the ?? operator, this has not been overridden. What this means is that it’s possible for one method of checking for nullity to disagree with another method. This can lead to some hard to debug issues, burning precious development time.

While null reference exceptions are an issue that many Unity developers encounter, the result of errors and unexpected behavior in your game are not outcomes many developers can afford. This is why it’s important to understand how null works in Unity, how to prevent null reference exceptions, and how to solve null reference exceptions.

What are the key ways to prevent null reference exceptions in your Unity games?

Null reference exceptions occur in Unity code in MonoBehaviour scripts when you attempt to access an object that is null. To prevent this, you’ll need to follow important best practices when writing your code. We’ll walk through a few effective methods below.

Use the ?. operator

The null-conditional operator (?.) allows you to access members of an object if the object isn’t null. After accessing this object, if the object is null (and the code therefore invalid), the rest of the line is harmlessly skipped. Here is how you can use it to prevent null reference exceptions.

gameObject?.GetComponent<AComponent>()?.SomeMethod(args)

Initialize variables to default values

To avoid null reference exceptions in Unity, you should initialize your variables to default values when they are declared. Here is an example of code you can use to do so.

// Initialize a blank default to ensure that
// you're not working with an uninitialized variable.
SomeCustomClass _instanceOfClass = new SomeCustomClass();

// As an alternative when working with Monobehaviours, 
// set up all of the default values on a Prefab and then:
[SerializeField] GameObject _somePrefab;

Start() {
	var instance = Instantiate(_somePrefab);
	// Do what you need/want with the instance from here.
}

Try lazy initialization patterns

The idea behind lazy initialization is that, rather than initializing a variable when it is created, you initialize it the first time you need it; we recommend doing this with custom getter properties in order to enforce the necessary intermediary steps. You can use the code below for this initialization.

// The below WILL default to null.
SomeMonoBehaviour _someMonoBehaviourInstance = default;
SomeMonoBehaviour SomeMonoBehaviourInstance 
{
	get 
	{
		// Using a property with a wrapped getter guarantees
		// that variable will be set when we use the property
		// in a lazy (just-in-time-initialization) manner
		if (_someMonoBehaviourInstance == null)
			_someMonoBehaviourInstance = FindReference(args);
		return _someMonoBehaviourInstance;
	}
}

How can you solve null reference exceptions?

If you’re past the point of prevention and you’re attempting to solve null reference exceptions, then it’s imperative that you understand all the issues that affect your game. This includes the ability to spot issues in both the native and Unity layers.

Having the right data to solve your issues is vital. Not only does it make the process of problem solving more efficient, it also prevents other issues from occurring. For example, if you’re solving your null reference exceptions properly, then in most cases, argument null exceptions in Unity won’t occur. This frees up valuable developer time.

Each coding language differs in its classification of what defines an exception. This is why you need detailed data about your mobile game. You also need the ability to pull from a variety of data sources, metrics, and user behaviors to reproduce what led to the exception. Make sure you have the following:

C# stack traces for unhandled exceptions

When a null reference exception occurs in C#, the stack trace from this provides vital information to get to the root of your issue.

The raw details of a crash stack trace.

You should know which function the exception comes from. That way, you can note every place in the function where the code accesses a member of a reference type. This will give you all the potential sites where the NullReferenceException occurs.

From here, you can begin an educated trial and error process where you check the origin of the references to note if any are guaranteed to be non-null.

User session insights

It’s important not only to have the crash stack trace but also to understand the user journey that led to the crash. This will give you valuable insight into the frustrations that users are experiencing, the user actions that led to the issue, and help you recognize patterns that may be related to the null reference exception.

Image of the details of a session timeline.

You should be able to look up any session for an in-depth view of the user experience. You should also be able to note important metrics like the speed of your game’s startup, the success of your network calls, and the frequency of errors and app freezes. In addition to this, you should have insight into other important factors like screen taps, low memory warnings, connectivity switches, and more all at a glance.

Final thoughts

Understanding null reference exceptions in Unity is crucial. It can be the difference between a successful game that delights users and a failing game that frustrates them.

Beyond just understanding null reference exceptions in Unity, it’s important to understand your game as a whole. Without the ability to monitor your game in detail, you’ll run into unexpected problems like errors, crashes, and ANRs. This can all lead to a loss of users, decreased revenue, and a poor business outcome. If you’re seeking mobile game success, start with a sound understanding of null and a holistic monitoring platform that suits your needs.

Interested in solving your issues with null reference exceptions today? You can get started for free