I have a few GameObjects with a DontDestroyOnLoad attached to them as I want them to load in level 2 scene but in other scenes such as MainMenu, Tutorial, GameOver, GameWin and Credits, I want them to be destroyed as my scene is not loading. When player dies, the scene GameOver does not load properly. See image.
Also this is my current script for the dontdestroyonload as I tried getting the current scene build index and adding if its a build index of 6 then delete (6 is my game over).
I am quite new to Unity so please be patient as this is all new to me and have had this problem for a while and can’t seem to fix it so a solution would be fantastic!
public void Start()
{
int indexOfCurrentScene = SceneManager.GetActiveScene().buildIndex;
if (indexOfCurrentScene == 6)
{
Destroy(gameObject);
}
DontDestroyOnLoad(gameObject);
}
What you need is to more cleanly break the lifetimes of these objects. For instance, something above tracking a score might be considered a “Score Manager” or “Game Manager.”
It would appear at the start of a game, and it would get destroyed AFTER the game.
If it has to survive a bunch of scene changes in between then it needs to be marked DontDestroyOnLoad.
But that also means it should not be recreated afresh when the next scene comes.
So here’s where all this long-rambling is going… it’s often better NOT to put anything in the scene, and then have a piece of code attempt to access it and have it join the scene transparently right at that instant.
This construct is called a Singleton. In this case it can also be destroyed. See the notes at the bottom.
Some super-simple Singleton examples to take and modify:
Simple Unity3D Singleton (no predefined data):
Unity3D Singleton with a Prefab (or a ScriptableObject) used for predefined data:
These are pure-code solutions, do not put anything into any scene, just access it via .Instance!
If it is a GameManager, when the game is over, make a function in that singleton that Destroys itself so the next time you access it you get a fresh one, something like:
public void DestroyThyself()
{
Destroy(gameObject);
Instance = null; // because destroy doesn't happen until end of frame
}
Looking at what you said, I vaguely understand what you mean and then the code just looks confusing. However, from what you said, am I right in thinking I make a script that says
private static SingletonSimple _Instance;
public static SingletonSimple Instance
{
get
{
if (!_Instance)
{
_Instance = new GameObject().AddComponent<SingletonSimple>();
// name it for easy recognition
_Instance.name = _Instance.GetType().ToString();
// mark root as DontDestroyOnLoad();
DontDestroyOnLoad(_Instance.gameObject);
}
return _Instance;
}
}
and just leave that in my script folder since it will run? So what about the game objects with dont destroy on them as I still want them to work in level 2 just not the rest. It is literally working on 1 scene the rest I want destroyed.
Correct. The instant you attempt to access that thing via its Instance property, the getter above creates one for you. That will be the same one until you explicitly Destroy() the gameObject associated with it, as I outlined above.
I am going to sound dumb but I made the script and have errors under ‘SingletonSimple’ what should that be?
Also, I find this langauge very interesting so I bought a book to learn further as things like this is confusing and would rather learn everything there is to do with C sharp.
So, another silly question… what about the game objects I dont want to destroy… What happens to them? Do I need a script on them to just say dont destroy on load
The above singleton is one that won’t destroy by itself… that’s why you would put in a function like I listed above and at the end of the game, explicitly destroy it so next time you get a fresh one.
MySingletonGameManager.Instance.DestroyThyself(); // at end of game
Objects marked DDOL are just moved to a temporary special scene in the scene view, and you can see them there.