Search Unity

Discussion Error: some objects were not cleaned up when closing the scene

Discussion in 'Editor & General Support' started by Chris-Ender, Aug 22, 2022.

  1. Chris-Ender

    Chris-Ender

    Joined:
    May 23, 2015
    Posts:
    12
    Hello,

    When stopping playmode while playing in certain levels I get reproducably an error message in the console that some objects are not cleaned up. Unity is right, I found the problem. The question is how to fix it properly.

    So I have a manager script in a singleon pattern to cover the most basic functions of the game. When playmode stops its OnDestroy() method is called. I have tons of other scripts accessing this manager script during normal execution. One has a call to the manager in its OnDestroy() method and when leaving playmode this is executed and - ups - the manager is already gone!

    So is there a proper way to tell all other scripts doing its OnDestroy and as last script do OnDestroy of the manager script?

    I already know about the definition of execution order at startup, the OnApplicationQuit() event and hooking into the Playmode change event.

    As you see in my posted scripts accessing the instance of the manager script Services.cs during shutdown now prints the message "Services: Accessing while application is quitting.", but it does not fix the problem of script execution order.

    Thanks,
    Chris
     
    Last edited: Aug 22, 2022
  2. Chris-Ender

    Chris-Ender

    Joined:
    May 23, 2015
    Posts:
    12
    Code (CSharp):
    1.  
    2. public class SingletonMono<T> : MonoBehaviour where T : MonoBehaviour
    3. {
    4.     protected static T instance;
    5.     protected static bool applicationIsQuitting;
    6.  
    7.     public static T Instance
    8.     {
    9.         get
    10.         {
    11.             if (instance == null)
    12.             {
    13.                 if (applicationIsQuitting)
    14.                 {
    15.                     Debug.LogError($"Singleton: Accessing while application is quitting.");
    16.                 }
    17.                 Dbg.LogError($"Singleton: instance not set of type '{typeof(T).ToString()}'.");
    18.             }
    19.             return instance;
    20.         }
    21.     }
    22.  
    23.     protected virtual void Awake()
    24.     {
    25.         instance = this.gameObject.GetComponent<T>();
    26.     }
    27.  
    28.     void OnDestroy()
    29.     {
    30.         instance = null;
    31.         applicationIsQuitting = true;
    32.     }
    33. }
    34.  
     
    Last edited: Aug 22, 2022
  3. Chris-Ender

    Chris-Ender

    Joined:
    May 23, 2015
    Posts:
    12
    Code (CSharp):
    1.  
    2. public class Services : SingletonMono<Services>
    3. {
    4.  
    5.     public static new Services Instance
    6.     {
    7.         get
    8.         {
    9.             // attention: Normally the app is started with the Init scene with proper initialization.
    10.             // In all other cases accessing the services leads to lazy loading of them.
    11.             if (instance == null)
    12.             {
    13.                 if (!applicationIsQuitting)
    14.                 {
    15.                     Dbg.LogWarning($"Services instance not set. Try to instantiate services now.");
    16.                     var loadedObject = Resources.Load("Services");
    17.                     if (loadedObject != null)
    18.                     {
    19.                         Dbg.Log($"Services instantiated. Try to initialize services now.");
    20.                         Instantiate(loadedObject, Vector3.zero, Quaternion.identity);
    21.                     }
    22.                     else
    23.                     {
    24.                         Dbg.LogError($"Services could not be loaded.");
    25.                     }
    26.                 }
    27.                 else
    28.                 {
    29.                     Debug.LogError($"Services: Accessing while application is quitting. Expect errors.");
    30.                 }
    31.             }
    32.             return instance as Services;
    33.         }
    34.     }
    35.  
    36. }
    37.  
     
  4. Chris-Ender

    Chris-Ender

    Joined:
    May 23, 2015
    Posts:
    12
    The problematic code is

    Code (CSharp):
    1.  
    2. public class SomeOtherScript : MonoBehaviour
    3. {
    4.         public void OnEnable()
    5.         {
    6.             Services.Instance.someMethod();  // works
    7.         }
    8.  
    9.         public void OnDisable()
    10.         {
    11.             Services.Instance.someMethod();  // crash, service is already cleaned up
    12.         }
    13.  
    14. }
    15.