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

Question Do scriptable objects initialise their fields automatically?

Discussion in 'Scripting' started by ShiftyGames, May 3, 2021.

  1. ShiftyGames

    ShiftyGames

    Joined:
    Sep 10, 2018
    Posts:
    16
    I can't seem to find the answer to this.

    In the following code, the condition in the if statement never evaluates true.

    Code (CSharp):
    1. public class WaveConfig : ScriptableObject
    2. {
    3.     [SerializeField] private GameObject pathPrefab;
    4.    
    5.     private List<Transform> waypoints = null;
    6.    
    7.     public List<Transform> Waypoints
    8.     {
    9.         get
    10.         {
    11.             if (waypoints  == null)
    12.             {
    13.                 waypoints = new List<Transform>();
    14.                 foreach (Transform waypoint in pathPrefab.transform)
    15.                 {
    16.                     waypoints.Add(waypoint);
    17.                 }
    18.             }
    19.  
    20.             return waypoints;
    21.         }
    22.     }
    23. }

    Yet the same condition but with MonoBehaviour works:

    Code (CSharp):
    1. public class ExperimentScript : MonoBehaviour
    2. {
    3.     private List<GameObject> gameObjects;
    4.  
    5.     public List<GameObject> GameObjects
    6.     {
    7.         get
    8.         {
    9.             if (gameObjects == null)
    10.             {
    11.                 Debug.Log("gameObjects is unassigned");
    12.  
    13.                 gameObjects = new List<GameObject>();
    14.             }
    15.             return gameObjects;
    16.         }
    17.     }
    18. }

    I have solved the ScriptableObject code by testing with Count:

    Code (CSharp):
    1. if (waypoints.Count == 0)
    It seems that the scriptable object initialises the List for me? Is that correct?
     
  2. vargata

    vargata

    Joined:
    Nov 26, 2013
    Posts:
    120
    yes its correct, it will be an empty list object, not null, just empty
     
  3. rubcc95

    rubcc95

    Joined:
    Dec 27, 2019
    Posts:
    222
    I was pretty sure that it is not like that, but you have made me doubt so I have checked and no, it is not like that.
    Unity only initialized by itself serialized fields (public fields and those marked with [SerializeField] attribute). At my pc code run exactly as I was specting...
     
  4. ShiftyGames

    ShiftyGames

    Joined:
    Sep 10, 2018
    Posts:
    16
    K this is weird. I made a new project, did everything you did in the video and it still doesn't work. Could it be something to do with Unity version? I'm using 2020.3.5f1.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    Scriptable Objects are veeeeery sneaky. If you have a private field (such as
    private bool Initialized;
    ), it will NOT be reset to false... its value will be persisted until your app quits or until you exit the editor.

    Mark it as
    [NonSerialized]
    to prevent this.
     
    sindharta_at_unity and Bunny83 like this.
  6. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,009
    Most important thing to understand is that ScriptableObject that you drag in editor to you components persist during application run (it is created once).
    It does not get reloaded after you load new scene and all modifications to it stays until application ends.
     
  7. ShiftyGames

    ShiftyGames

    Joined:
    Sep 10, 2018
    Posts:
    16
    I'm sorry, I'm not sure I understand. I added
    [System.NonSerialized]
    in front of the waypoints list, deleted any existing instances of the scriptable object, restarted Unity Editor, Unity Hub and Visual Studio, and after restart the waypoints List is still being initialized (not null).
     
    Last edited: May 3, 2021