I have a singleton GameManager class which is attached to a GameObject in each of my scenes. It has a member variable storing the current scene index.
Pressing Start button on the Main Menu calls StartGame which updates currentLevel from 0 to 1 and calls SceneManager.LoadScene for the game scene.
But when the Restart Level button on the game scene calls GameManager.RestartLevel, the currentLevel is at 0 again. It seems as if loading the new scene has reset the currentLevel variable to 0. I wasn’t expecting this in this singleton class.
I don’t understand why the changed value doesn’t persist - grateful for any help!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public static GameManager Instance = null;
private int currentLevel = 0;
void Awake()
{
Instance = this;
}
public void StartGame()
{
LoadLevel(1);
}
public void RestartLevel()
{
LoadLevel(currentLevel);
}
private void LoadLevel(int level)
{
currentLevel = level;
SceneManager.LoadScene(level);
}
}
You need to add DontDestroyOnLoad(gameObject); in Awake. Every time the scene loads it makes a new copy of the GameManager and resets the value making the new GameManager equal the static Instance.
Here is some code that I use for this type of thing:
void Awake()
{
if (!Instance)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
//Duplicate GameManager created every time the scene is loaded
Destroy(gameObject);
}
}
In every scene you have game object with this script. So far for N scenes you have N such objects. In the Awake method there’s instruction to set static variable to reference the current instance. Now scene #0 loads. The var is set to instance #0. Now scene #X loads. The var is reset to reference instance #x. And so on.
Yeah that seemed to work thanks - I thought I read that a singleton wouldn’t need the DontDestroyOnLoad call.
However, the “Restart Level” UI button I have in the game scene now no longer works, as the GameManager object whose function it tries to call has been Destroyed… How would I get around this - accessing a gameObject that isn’t present in the current scene?
Of course, the object from previous scene is destroyed when you loading next scene in exclusive mode. And if you set the reference only when it’s null, you obviously get the same result as before because that variable becomes null when scene is loaded and your program essetially doing the same - setting variable to newly loaded instance from every next scene