Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question NullReferenceException error when assigning a list to new()

Discussion in 'Scripting' started by cpjonas1104, Apr 1, 2024.

  1. cpjonas1104

    cpjonas1104

    Joined:
    Oct 20, 2020
    Posts:
    18
    Hi, I am working on a game where I need a script to find certain objects and add them to a list when the object is enabled. Here are the relevant bits of my code:
    Code (CSharp):
    1.    
    2.     public List<Bed> beds = new List<Bed>();
    3.     public List<Fridge> fridges = new List<Fridge>();
    4.     public List<Chair> chairs = new List<Chair>();
    5.     public List<Table> tables = new List<Table>();
    6.  
    7.     void OnEnable()
    8.     {
    9.         CheckForContains();
    10.         GridTester.instance.checkForContains.AddListener(this.CheckForContains);
    11.     }
    12.  
    13.     public void CheckForContains()
    14.     {
    15.         beds = new List<Bed>();
    16.         fridges = new List<Fridge>();
    17.         chairs = new List<Chair>();
    18.         tables = new List<Table>();
    19.      
    20.         //More stuff here
    21.     }
    Sadly I am getting an error I don't understand:
    NullReferenceException: Object reference not set to an instance of an object
    Room.CheckForContains () (at Assets/Scripts/Room.cs:57)
    Room.OnEnable () (at Assets/Scripts/Room.cs:30)

    The script lines that are referenced to in the CheckForContains function are the lines where I assign the list to a new and empty list. I am getting the error for all 4 lines.

    I have no idea why I should be getting this error, can anyone help me?
    Thank you :)
     
    Last edited: Apr 1, 2024
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,005
    The answer is always the same... ALWAYS!

    How to fix a NullReferenceException error

    https://forum.unity.com/threads/how-to-fix-a-nullreferenceexception-error.1230297/

    Three steps to success:
    - Identify what is null <-- any other action taken before this step is WASTED TIME
    - Identify why it is null
    - Fix that

    Generally, DO NOT make fields public if you're going to be modifying them in code. Unity WILL modify these fields as part of any normal serialization. Either make them public to drag stuff in and leave it alone, or make them private and provide an API to manipulate their contents. Here's why:

    Serialized / public fields in Unity are initialized as a cascade of possible values, each subsequent value (if present) overwriting the previous value:

    - what the class constructor makes (either default(T) or else field initializers, eg "what's in your code")

    - what may be saved with the prefab

    - what may be saved with the prefab override(s)/variant(s)

    - what may be saved in the scene and not applied to the prefab

    - what may be changed in the scene and not yet saved to disk

    - what may be changed in OnEnable(), Awake(), Start(), or even later

    Make sure you only initialize things at ONE of the above levels, or if necessary, at levels that you specifically understand in your use case. Otherwise errors will seem very mysterious.

    Here's the official discussion: https://blog.unity.com/technology/serialization-in-unity

    If you must initialize fields, then do so in the void
    Reset()
    method, which ONLY runs in the UnityEditor.

    Field initializers versus using Reset() function and Unity serialization:

    https://forum.unity.com/threads/sensitivity-in-my-mouselook-script.1061612/#post-6858908

    https://forum.unity.com/threads/crouch-speed-is-faster-than-movement-speed.1132054/#post-7274596

    To avoid complexity in your prefabs / scenes, I recommend NEVER using the
    FormerlySerializedAsAttribute