8
\$\begingroup\$

Since many users are facing the NullReferenceException: Object reference not set to an instance of an object error in Unity, I thought that it would be a good idea to gather from multiple source some explanation and ways to fix this error.


Symptoms

I am getting the error below appearing in my console, what does it mean and how do I fix it?

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

\$\endgroup\$
  • \$\begingroup\$ This seems like a general programming question & not game dev specific. OP's answer to own question includes a link to SO that covers this topic. \$\endgroup\$ – Pikalek Feb 2 '17 at 4:51
  • 2
    \$\begingroup\$ While the "NullReferenceException" is, indeed, a general programming question, here, the question covers specifically the exception in Unity : where can it be encountered in Unity programming, and how to solve them (see the various examples). \$\endgroup\$ – Hellium Feb 2 '17 at 8:01
  • \$\begingroup\$ @Pikalek, we have also broadened our scope for what we allow in terms of general programming. This was clarified when I asked about it in meta. I realise, now, that this might still fit the parameters of 'too generic', as per Josh's answer. \$\endgroup\$ – Gnemlock Feb 2 '17 at 8:31
  • \$\begingroup\$ The current answer also makes no note of anything specific to Unity (other than using Unity specific types in examples). It is, in fact, a generic programming response. We do not use answers in close arguments, but given it is a self answer, it does go towards supporting argument of intention. \$\endgroup\$ – Gnemlock Feb 2 '17 at 8:32
  • 3
    \$\begingroup\$ Unity has a few unique/characteristic ways to trigger these errors, through unassigned Inspector fields, failed GetComponent or Find attempts, or through its variant flavour "MissingReferenceException" when you had a valid reference but it got Destroy()ed. So, I think answers to this question in the context of Unity have good potential to be useful to the community, even if the Exception itself is very general. \$\endgroup\$ – DMGregory Feb 3 '17 at 17:41
9
\$\begingroup\$

Value type vs Reference type

In many programming languages, variables have what is called a "data type". The two primary data types are value types (int, float, bool, char, struct, ...) and reference type (instance of classes). While value types contains the value itself, references contains a memory address pointing to a portion of memory allocated to contain a set of values (similar to C/C++).

For example, Vector3 is a value type (a struct containing the coordinates and some functions) while components attached to your GameObject (including your custom scripts inheriting from MonoBehaviour) are reference type.

When can I have a NullReferenceException?

NullReferenceException are thrown when you try to access a reference variable that isn't referencing any object, hence it is null (memory address is pointing to 0).

Some common places a NullReferenceException will be raised:

Manipulating a GameObject / Component that has not been specified in the inspector

// t is a reference to a Transform.
public Transform t ;

private void Awake()
{
     // If you do not assign something to t
     // (either from the Inspector or using GetComponent), t is null!
     t.Translate();
}

Retrieving a component that isn't attached to the GameObject and then, trying to manipulate it:

private void Awake ()
{
    // Here, you try to get the Collider component attached to your gameobject
    Collider collider = gameObject.GetComponent<Collider>();

    // But, if you haven't any collider attached to your gameobject,
    // GetComponent won't find it and will return null, and you will get the exception.
    collider.enabled = false ;
}

Accessing a GameObject that doesn't exist:

private void Start()
{
    // Here, you try to get a gameobject in your scene
    GameObject myGameObject = GameObject.Find("AGameObjectThatDoesntExist");

    // If no object with the EXACT name "AGameObjectThatDoesntExist" exist in your scene,
    // GameObject.Find will return null, and you will get the exception.
    myGameObject.name = "NullReferenceException";
}

Trying to use the result of a getter that's returning null:

var fov = Camera.main.fieldOfView;
// main is null if no enabled cameras in the scene have the "MainCamera" tag.

var selection = EventSystem.current.firstSelectedGameObject;
// current is null if there's no active EventSystem in the scene.

var target = RenderTexture.active.width;
// active is null if the game is currently rendering straight to the window, not to a texture.

Accessing an element of a non-initialized array

private GameObject[] myObjects ; // Uninitialized array

private void Start()
{
    for( int i = 0 ; i < myObjects.Length ; ++i )
        Debug.Log( myObjects[i].name ) ;
}

Less common, but annoying if you don't know it about C# delegates:

delegate double MathAction(double num);

// Regular method that matches signature:
static double Double(double input)
{
    return input * 2;
}

private void Awake()
{
    MathAction ma ;

    // Because you haven't "assigned" any method to the delegate,
    // you will have a NullReferenceException
    ma(1) ;

    ma = Double ;

    // Here, the delegate "contains" the Double method and
    // won't throw an exception
    ma(1) ;
}

How to fix ?

If you have understood the previous paragraphes, you know how to fix the error: make sure your variable is referencing (pointing to) an instance of a class (or containing at least one function for delegates).

Easier said than done? Yes, indeed. Here are some tips to avoid and identify the problem.

The "dirty" way : The try & catch method :

Collider collider = gameObject.GetComponent<Collider>();

try
{
    collider.enabled = false ;
}       
catch (System.NullReferenceException exception) {
    Debug.LogError("Oops, there is no collider attached", this) ;
}

The "cleaner" way (IMHO) : The check

Collider collider = gameObject.GetComponent<Collider>();

if(collider != null)
{
    // You can safely manipulate the collider here
    collider.enabled = false;
}    
else
{
    Debug.LogError("Oops, there is no collider attached", this) ;
}

When facing an error you can't solve, it's always a good idea to find the cause of the problem. If you are "lazy" (or if the problem can be solved easily), use Debug.Log to show on the console information which will help you identify what could cause the problem. A more complex way is to use the Breakpoints and the Debugger of your IDE.

Using Debug.Log is quite useful to determine which function is called first for example. Especially if you have a function responsible for initializing fields. But don't forget to remove those Debug.Log to avoid cluttering your console (and for performance reasons).

Another advice, don't hesitate to "cut" your function calls and add Debug.Log to make some checks.

Instead of :

 GameObject.Find("MyObject").GetComponent<MySuperComponent>().value = "foo" ;

Do this to check if every references are set :

GameObject myObject = GameObject.Find("MyObject") ;

Debug.Log( myObject ) ;

MySuperComponent superComponent = myObject.GetComponent<MySuperComponent>() ;

Debug.Log( superComponent ) ;

superComponent.value = "foo" ;

Even better :

GameObject myObject = GameObject.Find("MyObject") ;

if( myObject != null )
{
   MySuperComponent superComponent = myObject.GetComponent<MySuperComponent>() ;
   if( superComponent != null )
   {
       superComponent.value = "foo" ;
   }
   else
   {
        Debug.Log("No SuperComponent found onMyObject!");
   }
}
else
{
   Debug.Log("Can't find MyObject!", this ) ;
}

Sources:

  1. http://answers.unity3d.com/questions/47830/what-is-a-null-reference-exception-in-unity.html
  2. https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it/218510#218510
  3. https://support.unity3d.com/hc/en-us/articles/206369473-NullReferenceException
  4. https://unity3d.com/fr/learn/tutorials/topics/scripting/data-types
\$\endgroup\$
  • \$\begingroup\$ This goes to a lot of effort to explain the "how to" of diagnosing the problem. I would not consider that an actual answer to the question "what is the problem". This also fails to address the answers that typically appear on these sort of questions. Perhaps this would be better over at the StackOverflow documentation? Perhaps not. \$\endgroup\$ – Gnemlock Feb 2 '17 at 0:20
  • 2
    \$\begingroup\$ I wouldn't say that using the debug log is lazy. For me, it's much faster to use the debug.log to narrow down the scope of where the error is occurring, then use the debugger to really find the error. But it always depend on the error at hand. In any case, I would not say using the debug log is lazy :P \$\endgroup\$ – Alexandre Vaillancourt Jun 7 '17 at 10:07
  • \$\begingroup\$ You should have also pointed out that it's not always a good idea to put checks for null. Even worse idea would be to use try/catch. The error tells you a lot about the problem you have there, and before beginners start putting null checks everywhere, you main problem is in the inspector as you forget to reference some object (drag object onto the script). I have seen a lot of code with try/catch and null checks in places where it's totally unnecessary. Debugging and working with a code like that is "a pain in the a**".Beginners learn about use cases of those checks and only then use them. \$\endgroup\$ – Candid Moon May 29 '18 at 14:57
  • \$\begingroup\$ I think that having a null check can be a good idea if an explicit Debug message is provided in the else. Having a NullReferenceException is not always self explanatory while No Rigidbody component attached to the gameObject directly explain what's wrong. I agree that just having the if( obj != null ) without message just "hides" the problem, and you can have a working project but not doing what you would expect without knowing why. \$\endgroup\$ – Hellium May 29 '18 at 15:34
4
\$\begingroup\$

While we can easily just do a check to ensure we are not trying to access a null reference, this is not always a suitable solution. Many times, in Unity programming, our problem may derive from the fact that the reference should not be null. In some situations, simply ignoring null references can break our code.

For example, it might be a reference to our input controller. It is great that the game does not crash due to the null reference exception, but we need to figure out why there is no input controller, and fix that problem. Without it, we have a game that may not crash, but can not take input, either.

Below, I will list possible reasons and solutions, as I come across them in other questions.


Are you trying to access a "manager" class?

If your trying to access a class that acts as a "manager" (that is, a class that should only ever have one instance running at a time), you might be better off using the Singleton approach. A Singleton class can ideally be accessed from anywhere, directly, by keeping a public static reference to itself. In this way, a Singleton can contain a reference to the active instance, which would be accessible without the trouble of setting up the actual reference every time.

Are you referencing the instance of your object?

It is common to simply mark a reference as public, so we can set the reference to the instance via the inspector. Always check that you have set the reference to an instance, via the inspector, as it is not uncommon to miss this step.

Are you instantiating your instance?

If we are setting up our object in code, it is important to ensure that we instantiate the object. This can be carried out using the new keyword and the constructor methods. For example, consider the following:

private GameObject gameObject;

We have created a reference to a GameObject, but it does not point to anything. Accessing this reference as is will result in a null reference exception. Before we reference our GameObject instance, we may call a default constructor method as follows:

gameObject = new GameObject();

The Unity tutorial on classes explains the practice of creating and using constructors.

Are you using the GetComponent<t>() method with the assumption that the component exists?

First, ensure that we always call GetComponent<t>() before we call methods from the component instance.

For reasons not worth going in to, we may assume our local game object contains a particular component, and try to access it with GetComponent<t>(). If the local game object does not contain that particular component, we will return a null value.

You could easily check if the returning value is null, prior to accessing it. However, if your game object should have the required component, it may be better to ensure that it at least has a default version of that component. We can tag a MonoBehaviour as [RequireComponent(typeof(t))] to ensure we always have that type of component.

Here is an example of a MonoBehaviour for a game object that should always contain a Rigidbody. If the script is added to a game object that does not contain a Rigidbody, a default Rigidbody will be created.

[RequireComponent(typeof(Rigidbody))]
public class AlwaysHasRigidbody : MonoBehaviour
{
    Rigidbody myRigidbody;


    void Start()
    {
        myRigidbody = GetComponent<Rigidbody>();
    }
}

Have you tried to re-build your project?

There are some cases where Unity may cause problems by trying to reference a cached version of a game object. In line with the age old "turn it off and on again" solution, try deleting your Library folder, and re-open Unity. Unity will be forced to re-build your project. This can solve some very peculiar instances of this problem, and should point to issues that would not come up in a final build.

\$\endgroup\$
  • 1
    \$\begingroup\$ I am still not sure if this question should be on topic. But here is a community wiki for users to post additional potential answers; So far it is comprised of the basics of the first half page of accepted answers for questions marked unity and "null reference" (that actually met the criteria of the question). \$\endgroup\$ – Gnemlock Feb 2 '17 at 9:10
-5
\$\begingroup\$

I see that there's an accepted answer. But, there is a better answer or suggestion for you for handling NullReferenceException. If you can relate programming in Java language like me, you can prevent from sending a null error by using the try-catch block. Try it for yourself! ;-)

If you're using in C#, check if you have using System; at the top of your script file. If not, add it. Now, you can use all sorts of Exception classes while try-catching a line of code.

If your're using UnityScript, use import System;

Here's an example:

using System; // --> This exact line of code. That's it.
using UnityEngine;

public class Test : MonoBehaviour {

    public GameObject player; // --> Example to check if there's a null content;

    public void Update() {

        // You may now catch null reference here.
        try {

            player.transform.Translate(0, 0, 2);

        } catch(NullReferenceException e) { // --> You may use this type of exception class

        }

    }
}

Also remember, you can catch also other exceptions such as MissingReferenceException, MissingComponentException, IndexOutOfRangeException, or any other exception classes as long as you include using System in your script.

That is all.

\$\endgroup\$
  • 2
    \$\begingroup\$ The try & catch method has been described in the accepted answer.... \$\endgroup\$ – Hellium Jun 7 '17 at 5:12

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.