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

Some objects were not cleaned up when closing the scene

Discussion in 'Scripting' started by etoreo, Dec 4, 2013.

  1. etoreo

    etoreo

    Joined:
    Apr 11, 2012
    Posts:
    104
    I have the following pattern in a few of my objects - it makes a great fake singleton. But I am getting the error "Some objects were not cleaned up when closing the scene" when I stop playing the scene when I use this pattern. Anyone know how I can clean up that error? It's getting very annoying.

    Code (csharp):
    1.  
    2.    protected static UnitsManagerScript sUnitsManagerScript;
    3.    public static UnitsManagerScript SceneInstance
    4.    {
    5.       get
    6.       {
    7.          if(!sUnitsManagerScript)
    8.          {
    9.             GameObject pGameObj = GameObject.Find("UnitsManager");
    10.             if(!pGameObj)
    11.                pGameObj = new GameObject("UnitsManager");
    12.             sUnitsManagerScript = pGameObj.AddComponent<UnitsManagerScript>();
    13.          }
    14.          return sUnitsManagerScript;
    15.       }
    16.    }
    17.  
     
  2. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    My guess is:

    "UnitsManager" is a game object that exists in your scene. You're adding a UnitsManagerScript component to it then holding on to a reference to that component in your sUnitsManagerScript variable. What this means is that your UnitsManager game object cannot be completely destroyed and garbage collected because it references the UnitsManagerScript which itself can't be destroyed because it is being referenced by your UnitsManagerScript. Add a method like this:

    Code (csharp):
    1.  
    2. public static void DestroyUnitsManager()
    3. {
    4.      sUnitsManagerScript = null;
    5. }
    6.  
    Try calling that method in the OnDestroy on a script attached to your UnitsManager object (like in your UnitsManagerScript). That should make sure your references are released and the object can be completely destroyed.
     
  3. etoreo

    etoreo

    Joined:
    Apr 11, 2012
    Posts:
    104
    You are correct, I have a "UnitsManager" in my scene after it starts and its persisted after ending the simulation.

    I tried adding this to my UnitsManagerScript convinced that your idea would work, but it did not...
    Code (csharp):
    1.  
    2.    public void OnDestroy()
    3.    {
    4.       sUnitsManagerScript = null;
    5.    }
    6.  
    That really was a good idea, but it doesn't work. Any other ideas?
     
  4. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Hmm... have you set a breakpoint and verified that OnDestroy is even firing? So... UnitsManagerScript inherits MonoBehavior....

    You should also try removing the component from the UnitsManager object. But looking at it here's your biggest issue:

    You have: UnitsManagerScript : MonoBehavior

    Now, UnitsManagerScript has a static property... sUnitsManagerScript. You're creating an instance of UnitsManagerScript (when you call AddComponent) and then you're assigning it as a reference to it's own property (if that makes sense)... except since it's a static property it's really part of the class definition and not the instance. I know there is another thread floating around about using a Singleton-ish Monobehavior... and there are some gotchas that were solved there.

    I found the thread... take a look here:

    http://forum.unity3d.com/threads/197169-Singleton-vs-Static

    It may help you fix up that pattern a bit to avoid the dangling reference issues.
     
  5. etoreo

    etoreo

    Joined:
    Apr 11, 2012
    Posts:
    104
    Thanks for the link. This is a lot of reading. So far, I'm not sure it will help with the dangling reference, but we will see...
     
  6. alti

    alti

    Joined:
    Jan 8, 2014
    Posts:
    94
    I was getting this error when I quit the application in the unity editor (and probably on builds; you know how that goes...) and I figured out why it's happening.

    When you quit the unity application, script order matters a lot (you can change the execution order of scripts by selecting a script in your project panel > select "execution order" at the top right of the inspector window once the script is selected > then clicking the "+" button to add it to the bottom of the list or wherever it needs to be.

    In other words: It is possible you are UNSUBSCRIBING to a delegate on a script that runs AFTER unity destroys the reference once the application quits.

    To avoid this error, complete the steps above OR simply go to your "OnDisable" function, or wherever you are unsubscribing from a delegate/function (if it's happening when quitting the game view, then it's likely ondisable or something like it), and check if the instance is null.

    for example:

    Code (CSharp):
    1. void OnDisable(){
    2.         if(DelegateHome.Instance != null){
    3.             DelegateHome.Instance.onTheCallBack -= TheFunctionInTheScriptWhereThisOnDisableFunctionIs;
    4.         }
    5.     }