Problem with DontDestroyOnLoad and scene/level loading


I have some objects in my menu scene to store data and pass to levels and it has a DontDestroyOnLoad flag set on it and it works great.

Problem is, when I load back into my menu scene, it creates another instance of that object and I end up with two of those!

How to solve it?


Best practice would be to have a pre-gameplay scene dedicated to DDOL objects, where you will instantiate and initialize evrything you’re going to need in all scenes. Once everything is ready, you can load your main menu, and never go back to that pre-gameplay scene, so you won’t have to worry about duplicates.

Here’s the complete and full explanation of how to do this.

It is dead simple - there’s just nothing to it. Couldn’t be easier:

You may be aware of the “Grid” system which I invented (years and years ago) and is very very popular now.

While using Grid.cs is great, be aware it is nothing more than syntactic candy to save you typing one line of code, ie FindObjectOfType, in itself Grid is nothing.

@corn approach is a valid solution that can work well in some cases.

Another option is to use a Singleton class. This enforce that only one copy of that class will be created plus it allows you to access it from any other script without having a direct reference. It is very useful for things like AudioManager, InputSystem, ScenesLoader and any other scripts where you want to guarantee a single copy and you want the ability to call them from various area of the code.

Just attach the following script to the GameObject in question.

Here is a simple example of Singleton implementation that worked well for me:

public class YourMonoBehaviour : MonoBehaviour
        private static YourMonoBehaviour instance;
    	public static YourMonoBehaviour Instance
    			if(instance == null)
    				instance = GameObject.FindObjectOfType<YourMonoBehaviour>();
    			return instance;
    	protected virtual void Awake()
    		if(instance != null && instance != this)
    		instance = this;

You can access it from other scripts with: YourMonoBehaviour.Instance