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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Bug Preloaded Assets are only loaded properly during script changes or opening project settings.

Discussion in 'Editor & General Support' started by Freznosis, May 2, 2020.

  1. Freznosis

    Freznosis

    Joined:
    Jul 16, 2014
    Posts:
    294
    Hello.

    I'm using this script here from the docs as a test. I've added 3 ScriptableObjects to the "Preloaded Assets" list in Unity. When ever I open the project for the first time and hit play, only the first asset in the list is pre-loaded. I confirmed this by using a simple Debug.Log. I can also confirm this because the ScriptableObject instances are null except for the very first asset at index 0 at play time.

    Here is what the console looks like when this happens.
    Unity_2020-05-01_17-11-00.png

    Now the weird part is that if I make a change to a script or open the Project Settings window, then the the rest of the assets are loaded. Any asset that wasn't pre-loaded will now be loaded and print to the console.

    Here is what the console looks like after making a script change or opening project settings window.
    Unity_2020-05-01_17-15-39.png

    After a script change or opening project settings, everything works fine and you can see by this log, the ScriptableObjects are loading as they should now when starting the game.
    Unity_2020-05-01_17-18-23.png

    I have confirmed this is not project related by creating a new project and dropping the script into the project and repeating this steps. I'm using Unity 2019.3, but also tested on 2019.2 with same outcome.

    Here is the script I'm using. Any ideas why this happens?
    Code (CSharp):
    1.   public class WheelReferences : ScriptableObject
    2.     {
    3.        
    4.         private static WheelReferences _instance;
    5.  
    6.         public static WheelReferences Instance
    7.         {
    8.             get { return _instance; }
    9.         }
    10.  
    11.         private void OnEnable()
    12.         {
    13.             _instance = this;
    14.             Debug.Log($"Instance for WheelReferences was set: {_instance!=null}");
    15.         }
    16.        
    17.        
    18.     #if UNITY_EDITOR
    19.     [UnityEditor.MenuItem("Assets/Create/Wheel References")]
    20.     public static void CreateAsset()
    21.     {
    22.  
    23.         WheelReferences asset = ScriptableObject.CreateInstance<WheelReferences>();
    24.         UnityEditor.AssetDatabase.CreateAsset(asset, "Assets/WheelReferences.asset");
    25.  
    26.         // Add the config asset to the build
    27.         var preloadedAssets = UnityEditor.PlayerSettings.GetPreloadedAssets().ToList();
    28.         preloadedAssets.Add(asset);
    29.         UnityEditor.PlayerSettings.SetPreloadedAssets(preloadedAssets.ToArray());
    30.     }
    31.     #endif
    32.     }
     
    reinfeldx and sean244 like this.
  2. sean244

    sean244

    Joined:
    Nov 4, 2017
    Posts:
    95
    I have this problem too. I added a scriptableobject to the Preloaded Assets but OnEnable does not get called when I load up the editor. I'm using 2019.4.18f1
     
  3. Freznosis

    Freznosis

    Joined:
    Jul 16, 2014
    Posts:
    294
    Hi, I've tried contacting Unity with bug reports but I haven't gotten any responses. As a workaround I've been using this solution: https://medium.com/@fiftytwo/fast-singleton-approach-in-unity-fdba0b5309d5

    It's been working great for me. Give it a try.
     
  4. sean244

    sean244

    Joined:
    Nov 4, 2017
    Posts:
    95
    I'll consider that. Creating a static class that calls Resources.Load in the constructor also works
    Code (CSharp):
    1. [InitializeOnLoad]
    2. public static class Initializer
    3. {
    4.     private static readonly MyScriptableObject _myScriptableObject
    5.  
    6.     static Initializer()
    7.     {
    8.         if (!SessionState.GetBool("FirstInitDone", false))
    9.         {
    10.            _myScriptableObject = Resources.Load<MyScriptableObject>("MyScriptableObject");
    11.            SessionState.SetBool("FirstInitDone", true);
    12.         }
    13.     }
    The SessionState bool ensures that it only runs the first time the project is launched, rather than every single time the code is recompiled.