Originally posted on: http://geekswithblogs.net/jkrebsbach/archive/2014/08/11/unity-dontdestroyonload-causing-scenes-to-stay-open.aspx
My Unity project has a class (ClientSettings) where most of the game state & management properties are stored. Among these are some utility functions that derive from MonoBehavior. However, between every scene this object was getting recreated and I was losing all sorts of useful data. I learned that with DontDestroyOnLoad, I can persist this entity between scenes. Super.
The problem with adding DontDestroyOnLoad to my "ClientSettings" was suddenly my previous scene would stay alive, and continue to execute its update routines. An important part of the documentation helps shed light to my issues:
"If the object is a component or game object then its entire transform hierarchy will not be destroyed either."
My ClientSettings script was attached to the main camera on my first scene. Because of this, the Main Camera was part of the hierarchy of the component, and therefore was also not able to destroy when switching scenes. Now the first scene's main camera Update routine continues to execute after the second scene is running - causing me to have some very nasty bugs.
Suddenly I wasn't sure how I should be creating a persistent entity - so I created a new sandbox project and tested different approaches until I found one that works:
In the main scene: Create an empty Game Object: "GameManager" - and attach the ClientSettings script to this game object.
Set any properties to the clientsettings script as appropriate.
Create a prefab, using the GameManager.
Remove the Game Object from the main scene.
In the Main Camera, I created a script: Main Script. This is my primary script for the main scene.
<code>
public GameObject[] prefabs;
private ClientSettings _clientSettings;
// Use this for initialization
void Start () {
GameObject res = (GameObject)Instantiate(prefabs[0]);
}
</code>
Now go back out to scene view, and add the new GameManager prefab to the prefabs collection of MainScript.
When the main scene loads, the GameManager is set up, but is not part of the main scene's hierarchy, so the two are no longer tied up together.
Now in our second scene, we have a script - SecondScript - and we can get a reference to the ClientSettings we created in the previous scene like so:
<code>
private ConnectionSettings _clientSettings;
// Use this for initialization
void Start () {
_clientSettings = FindObjectOfType<ConnectionSettings> ();
}
</code>
And the scenes can start and finish without creating strange long-running scene side effects.