Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

The big Null Reference Exception thread

Discussion in 'Scripting' started by dterbeest, Jun 20, 2014.

  1. dterbeest

    dterbeest

    Joined:
    Mar 23, 2012
    Posts:
    389
    Every day we see multiple threads popping up with questions about Unity throwing a Null Reference Exception. My goal for this post is to explain what a Null Reference Exception is and how you can prevent them from coming happening. This is just a basic explanation with which you will be able to fix 99% of your NullReferenceException errors.

    I would like to apologise for my poor English, it is not my native language.

    What is Null?
    Null is the equivalent of "No value".
    It basically means, you have declared a variable, but it is not assigned yet.

    But in my example i clearly assign a value to my variable!
    Consider the following example:
    Code (csharp):
    1. function Foo() {
    2.   var some : Something = GetComponent(Something);
    3.   some.bar = 42;
    4. }
    Here we declare the variable some, which is of type Something. We clearly assign a value to it by calling GetComponent(Something)
    But what happens when there is no component called of type Something?
    In that case the GetComponent function returns null, because it has to return something.

    So what happens if we try to set the some.bar to 42 when some equals null? Well, since null is nothing, it means that the .bar variable is not there either (nothing cannot contain a variable)
    This is where Unity will throw you a NullReferenceException.

    Ok, I get it, but how do I find out what exactly is going wrong?
    Whenever Unity throws you an exception they also state the script name and the line number where the exception is happening. In the example above the exception would happen at line number 3.

    So how to prevent them?
    The basic and most used thing to do is to implement a simple null checking routine.
    Code (csharp):
    1. function Foo() {
    2.   var some: Something = GetComponent(Something);
    3.   if (some != null) {     //here we check if some does not equal null
    4.     some.bar = 42;
    5.   }
    6. }
    The example above is OK when it is not needed to set the some.bar value to 42. However, since you are busy creating your game and you know it will be needed to set that value you will do better to either give a more descriptive error using Debug.LogError("some is null") or using SystemUtilities.ThrowExceptionIfNull(some, "some is null")
    In that case the example would be:
    Code (csharp):
    1. function Foo() {
    2.   var some: Something = GetComponenet(Something);
    3.   if (some == null) {    //here we check if some does equal null
    4.     Debug.LogError("You forgot to add a Something component to " + name);
    5.     return;  //return will exit the function, everything after this is not executed.
    6.   }
    7.   some.bar = 42;
    8. }
    9. //or use
    10. function Foo() {
    11.   var some: Something = GetComponent(Something);
    12.   SystemUtilities.ThrowExceptionIfNull(some, "You forgot to add a Something component to " + name);
    13.   some.bar = 42;
    14. }
    15.  



    Handy links:
    http://answers.unity3d.com/questions/177392/what-is-null.html
    http://answers.unity3d.com/questions/51331/how-to-check-if-something-is-null.html
    http://www.google.com (!!!)


    I hope this will come in handy for everyone struggling to get their code to run
     
    Last edited: Jun 20, 2014
    Erisat likes this.
  2. Pati-Co

    Pati-Co

    Joined:
    Jan 9, 2014
    Posts:
    56
    I use one little script which check if object is null and raise ecxeption if it is null.
    It looks somethink like this:
    Code (csharp):
    1. SystemUtility.ThrowExceptionIfNull(some, "some is null");
    It makes my checks shorter and easier to read and understand.
    Since I use it, I forget about NullReferencesExceptions ;)
     
    dterbeest and Erisat like this.
  3. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    dterbeest, maybe the possibility of having a null variable is part of your design then checking for null value is fine.

    On the other hand, if your game needs that value to be set to the great answer and will not work properly without, then you should embrace the exception. This way when you run your game in the editor you know that you forgot to add the damned script !

    The null check used where it should not would be as wrong as a compiler embeding every variable use in one, if you happen to have any missing reference, your project is going to be impossible to debug because you won't know where the problem is.

    Patico's, could you elaborate the goal of your utility since you'll get the exception anyways if you try to read a null object's inner values..
     
  4. dterbeest

    dterbeest

    Joined:
    Mar 23, 2012
    Posts:
    389
    Thanks! Suggestions have been added to OP
     
    _met44 likes this.
  5. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,731
    I sometimes use a null value as a return from functions (to indicate no object found for example), as long as it is checked for and the correct action taken there is no problem.
     
  6. dterbeest

    dterbeest

    Joined:
    Mar 23, 2012
    Posts:
    389
    It is inevitable to do that sometimes.

    Code (csharp):
    1.  public class Foo {
    2.   List<Bar> bars = new List<Bar>();
    3.  
    4.   public Bar GetBar(string barName) {
    5.     foreach(Bar b in bars) {
    6.       if (b.barName.Equals(barName)) {
    7.         return b;
    8.       }
    9.     }
    10.     return null;  //nothing found
    11.   }
    12. }
    GetComponent works in roughly the same way
     
  7. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    I must add something if you want to go this route, if you intend to not have the script on some object using this one, the condition should be reversed:

    Code (CSharp):
    1. function Foo() {
    2.   var some: Something = GetComponent(Something);
    3.   if (some) {    //here we check if some isn't null
    4.      some.bar = 42;
    5.   }
    6. //Do some other stuff
    7. }
    Imagine you intend to setup various scripts this way, it's easier to do it this way than the other way arround. And if a script is mandatory, you should add the RequireComponent attribute anyways ;).
     
  8. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    The only difference between this and the OP is that your way is less readable, the condition is the same, you're not reversing anything. The only reason if(some) even works is because UnityEngine.Object overrides the Equals() function, which internally does the same thing
     
  9. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    ok if you like the syntax better this way, you can write != null. Doesn't change the test is done the other way arround and that it'll allows for this variable to be null without blocking the rest of that Start() method...
     
  10. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    I don't really understand your point.

    if(some) is equivalent to if(some != null), you aren't gaining anything
     
  11. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    The original test was if(some == null) and existing the method if that was true. Meaning that if the script wasn't present, you didn't do anything else in this method.

    And as I stated, if the script is mandatory, not checking and relying on the default error throwing is fine since you shouldn't go forward with your project with missing mandatory scripts anyways (and that shouldn't happen since you should use the RequireComponent attribute for mandatory side scripts anyways)
     
  12. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    This is the version in the OP I was talking about
     
  13. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    Oh I see, sorry :p

    But anyways you didn't warned people it would prevent them from seeing where a bug comes from and that was my main point...

    And now that I'm thinking of it, people who needed the tip won't remember the warning when it comes to it. That's why I prefered the crashing version in the first place, at least they have to look at their code and see what mistake was made and where, instead of wasting a night thinking they're hallucinating about the behaviour happening in the game ;)