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
  3. Dismiss Notice

Question Title: InvalidOperationException When Using RuntimeInitializeOnLoadMethod in Build Version

Discussion in 'Scripting' started by AmadeusSalieri, May 17, 2024.

  1. AmadeusSalieri

    AmadeusSalieri

    Joined:
    Jan 4, 2021
    Posts:
    16
    Question:



    I am trying to create a singleton object that is automatically instantiated. Below is the code I have written:
    Code (CSharp):
    1.  
    2.  
    3. public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
    4. {
    5.     private static T _instance;
    6.  
    7.     public static T Instance
    8.     {
    9.         get
    10.         {
    11.             if (_instance == null)
    12.             {
    13.                 _instance = (T)FindObjectOfType(typeof(T));
    14.  
    15.                 if (_instance == null)
    16.                 {
    17.                     GameObject obj = new GameObject(typeof(T).Name, typeof(T));
    18.                     _instance = obj.GetComponent<T>();
    19.                 }
    20.             }
    21.  
    22.             return _instance;
    23.         }
    24.     }
    25.  
    26.     protected virtual void Awake()
    27.     {
    28.         if (transform.parent != null && transform.root != null)
    29.         {
    30.             DontDestroyOnLoad(this.transform.root.gameObject);
    31.         }
    32.         else
    33.         {
    34.             DontDestroyOnLoad(this.gameObject);
    35.         }
    36.    
    37.         var findedObjects = FindObjectsByType<T>(FindObjectsSortMode.None);
    38.         if (findedObjects.Length > 1)
    39.         {
    40.             Destroy(gameObject);
    41.         }
    42.     }
    43.  
    44.     [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
    45.     private static void Initialize()
    46.     {
    47.         SelfInstantiate();
    48.     }
    49.  
    50.     private static void SelfInstantiate()
    51.     {
    52.         if (_instance == null)
    53.         {
    54.             GameObject obj = new GameObject(typeof(T).Name, typeof(T));
    55.             _instance = obj.GetComponent<T>();
    56.         }
    57.     }
    58. }

    However, I encounter the following error in the build version:
    Code (bash):
    1. InvalidOperationException: Could not execute the method because the containing type 'Singleton`1[T]' is not fully instantiated.
    I have tried using both RuntimeInitializeLoadType.BeforeSceneLoad and RuntimeInitializeLoadType.AfterSceneLoad, but the error persists.


    What I have tried:



    • Attempted to initialize the singleton with both RuntimeInitializeLoadType.BeforeSceneLoad and RuntimeInitializeLoadType.AfterSceneLoad.

    • Verified the code works without errors in the Unity Editor.



    Question:



    What is causing this error in the build version, and how can I resolve it?
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,390
    Rather than have it self-instantiate via RuntimeInitializeOnLoadMethod, have it self-instantiate when it's first accessed.

    Also, does this need to be a monobehaviour?
     
  3. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,922
    Feel free to use my MonoSingleton. This has all kinks worked out AND you can use it both ways, either it instantiates a gameobject and adds itself to it when first accessing the Singleton instance, or you can add it as a component to a game object and it will use that instance.

    In both cases the singleton resides in DontDestroyOnLoad and prevents duplication or deliberate / accidental Destroy because a singleton's lifetime should only end when the application quits. This may seem a little restrictive but it helps to prevent common issues.