DontDestroyOnLoad not working
I have the following:
public class Singleton : MonoBehaviour
{
private static Singleton _instance = null;
public static Singleton Instance
{
get { return _instance; }
}
void Awake()
{
if (_instance != null && _instance != this)
{
Destroy(gameObject);
return;
}
_instance = this;
DontDestroyOnLoad(gameObject);
}
}
I add the component to an Object (Transitions) expecting it will last for the next load, then when I load the next scene, my object is destroyed.
The GO Transition has another script attached and it's children have another script attached.
Any ideas on why DontDestroyOnLoad is not working?
Are you sure there's no other code that could destroy it. As posted that code should work.
Is the script also on some other object (which would "claim" _instance
?) Try printing Singleton.Instance.transform.name;
I use the same pattern in a project of $$anonymous$$e. It works for me. There must be something else that interferes.
Answer by sotirosn · May 14, 2013 at 05:23 PM
I was having the same issue as you and then I realized that my singleton was not a root GameObject and its parent was being destroyed, thus destroying it as a child..
To fix this instead did: DontDestroyOnLoad(transform.root.gameObject);
which then introduced all kinds of problems with duplicate root objects, which I then had to merge all of the non-singleton objects together into under a single singleton root. Kind of a pain, but in the end it was worth it for a nested singleton.
Wow... all I needed to do was move the object to be a root object (not nested in something else) and it worked as expected. It's pretty incredible how this isn't even mentioned in the documentation. DontDestroyOnLoad does NOT work unless the object in question is not under any other object.
Answer by guybrush.threepwood · Mar 12, 2015 at 06:08 PM
What worked for me was, that I moved it to root on awake the first time. So I could leave it nested in my prefab.
void Awake()
{
if (instance != null && instance != this)
{
Destroy(this.gameObject);
return;
}
else
{
// just move it to the root
this.transform.parent = null;
instance = this;
this.LoadAd();
}
DontDestroyOnLoad(this.gameObject);
}
Answer by codecranker · Apr 20, 2013 at 03:15 AM
I didnt quite understood the logic behind defining a singleton MonoBehavior class. What do you gain by making it singleton?
why not just do DontDestroyOnLoad(gameObject) inside Awake() and then use GameObject.Find("singleton").GetComponent()?
There are several reasons:
It's much faster than using GameObject.Find
It's more robust than GameObject.Find (if you change the name it still works)
It provides intellisense in the code editor to find the object (you don't have to go and look it up in the editor)
You can provide clever initialization to create the object if it doesn't exist
This is obviously even more useful if there are multiple components accessing the singleton.
Also Awake() is called each time a level is reloaded so if for example your player dies 3 times then you will have 3 high score keepers alive because each one called Don'tDestroyOnLoad().
$$anonymous$$aybe worth pointing out that what you're all talking about about here is just a particular kind of singleton. There's nothing to say a singleton monobehaviour has to use DontDestroyOnLoad at all.
Answer by MaxLohMusic · Mar 28 at 08:44 AM
In line with the answer by sotirosn, in my case it was even simpler: The only thing I needed to do was move the object to not be nested under any other game object. Just make sure it's right under the scene. It then worked as expected. It's pretty incredible how this isn't even mentioned in the documentation. DontDestroyOnLoad does NOT work unless the object in question is not under any other object.