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

List in ScriptableObject gets NullReferenceException in the build, but returns objects in the Editor

Discussion in 'Scripting' started by Piotrone, Sep 23, 2020.

  1. Piotrone

    Piotrone

    Joined:
    Mar 6, 2015
    Posts:
    36
    Hi all,

    I get a "NullReferenceException: Object reference not set to an instance of an object" when calling GetLevel in the build (iOS), whereas in the Editor the methods returns an object.

    The list isn't empty because Debug.Log(levelList.Count) returns "3" in the build (this matches the number of objects referenced in the inspector)

    I've tried to recreate the ScriptableObject and add the objects to levelList again in the inspector, but it didn't fix the issue.

    Also Debug.Log(GetLevel(1)) causes the "NullReferenceException: Object reference not set to an instance of an object"

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. [CreateAssetMenu(menuName = "Data file/Level catalog")]
    5. public class LevelCatalog : ScriptableObject {
    6.  
    7. [SerializeField] private List<Object> levelList = new List<Object>();
    8.  
    9.     public int Count
    10.     {
    11.     get
    12.         {
    13.         return levelList.Count;
    14.         }
    15.     }
    16.  
    17.     public Object GetLevel (int index)
    18.     {
    19.         if(index >= levelList.Count || index < 0)
    20.         {
    21.             return null;
    22.         }
    23.         return levelList[index];
    24.     }
    This is where I call GetLevel from

    Code (CSharp):
    1. public class LevelSelector : MonoBehaviour
    2. {
    3.     public SceneFader sceneFader;
    4.     public LevelCatalog playableLevels;
    5.     public LevelSelectButton buttonPrefab;
    6.     public Transform containerPanel;
    7.  
    8.     private void Start()
    9.     {
    10.         for (int i = 0; i < playableLevels.Count; i++)
    11.         {
    12.             if (buttonPrefab != null)
    13.             {
    14.                 LevelSelectButton newButton = Instantiate(buttonPrefab, containerPanel);
    15.                 newButton.Initialise(this, playableLevels.GetLevel(i).name, i);
    16.             }
    17.         }
    18.     }
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,832
    One common reason for a serialized variable to be null in a build but not when running in the editor is the Unity inspector.

    When you look at an object in the Unity inspector, it forces Unity to serialize all of the serializable fields, and then deserialize them back into the object so that it will pick up any changes you make.

    As part of this process, Unity automatically creates default objects for any variables that are null (except for a few special types like Component and its derivatives). So if you have some code somewhere that sets the variable to null, then when running in a build it will stay null until you set it to something else, but if you are running in the editor and look at that object in the inspector, the null will get replaced by a default object. This can lead to some rather confusing bugs.

    Do you have any code anywhere that could set levelList to null under any circumstances?
     
  3. Piotrone

    Piotrone

    Joined:
    Mar 6, 2015
    Posts:
    36
    Thank you @Antistone. No, I don't use levelList anywhere else, and I don't set it to null under any circumstances.

    I'm using the List<Object> to reference Scenes in the inspector, as Scenes inherit from Object.

    But after some additional research I discovered that "Scenes are editor-only assets, so they disappear when you actually create a build". So I tested my script again with non-Scene objects and I don't get the NullReferenceException anymore.

    Luckily that post also provide some workarounds.
     
    Kurt-Dekker likes this.
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    Yeah, been bitten by that one. Fairly infuriating. Scenes should have been assets (represented by classes) just like other assets on disk but for some bizarre reason Unity chose to make a Scene object a struct, which means you can't pass it around by reference either.
     
  5. zidraf123

    zidraf123

    Joined:
    Jan 27, 2019
    Posts:
    1
    How do you fix this?