Singleton GameManager with DontDestroyOnLoad acting weird

Hi,

I’ve setup a Script called GameManager which has a static instance variable with DontDestroyOnLoad. It is not part of the hierarchy before game launch and is not instantiated, just created. Therefore, when I exit play mode in testing, the game leaves the GameObject without destroying them.

When the level loads, it checks if there is an instance of the GameManager, if not it will check if there is a GameObject around with the GameManager type, and if not it will create it. I do all this in the getter of the class.

I have a Camera in each scene and I do destroy that on load. The Camera calls the GameManager to “activate” it through the getter on Awake.

The problem that occurs is that for some reason, if I run Level1.scene, everything works fine. If I complete the level the game loads Level2.scene. Everything fine now as well. At this point if I exit the play mode, and re-enter playmode. Level1 is again, fine. But when I complete the level and load Level2.scene, it… “works” but it does re-create the GameManager. The only difference between the runs is that Level2.scene had no GameManager in the first load. It then created them and for some reason saved them to the scene for the next load.

I guess this would be fine, it would be better if they deleted the GameObject no matter how I left the application. But the question remains, why does it re-create it instead of finding the already exsisting GameManager if that’s the case?

To illustrate this another way, the code below generates the following Debug output:

Case1: (never loaded either scene)
Level1.scene
“no instance” ← expected
“no object” ← expected
“waking up” ← expected
Level2.scene
(nothing) ← expected
Case2: (quit play and loaded just level 1)
Level1.scene
“waking up” ← expected
“no instance” ← expected
Case3: (quit play and went through level 1 to level 2)
Level1.scene
“waking up” ← expected
“no instance” ← expected
Level2.scene
“no instance” ← not sure about this one
“no object” ← what?
“waking up”

public class GameManager : MonoBehaviour {
 
    static GameManager _instance;
 
    static public bool isActive {
        get {
            return _instance != null;
        }
    }
 
    static public GameManager instance
    {
        get
        {
            if (_instance == null)
            {
                Debug.Log("no instance");
                _instance = Object.FindObjectOfType(typeof(GameManager)) as GameManager;
             
                if (_instance == null)
                {
                    Debug.Log("No object");

                    GameObject go = new GameObject("[GameManager]");
                    DontDestroyOnLoad(go);
                    _instance = go.AddComponent<GameManager>();
                }
            }
            return _instance;
        }
    }
 
    void Awake () {

        Debug.Log("Waking up");
    }
}

Added an OnDestroy() call, and it seems the GameManager does get destroyed in Case 3 when leaving Level1.scene
Which means that the DontDestroyOnLoad for go is either removed when the object is left in the hierarchy or something else is going on.
Now, the question is why…

Also tried adding a DontDestroyOnLoad(_instance); after setting the _instance