- Home /
Unity Singelton - Dont destroy on load
Am not quiet sure what exactly is the issue in my code below. Am not able to save the game object with its component between the scene. I have created the singleton and dont destroy on load.
Problem: Once I get back to the scene all the buttons and other components are not working at all. Is there any issue with my code?
private static startScreen_Manager _startScreen_ManagerInstance;
public static startScreen_Manager startScreen_ManagerInstance
{
get
{
if(_startScreen_ManagerInstance == null)
{
_startScreen_ManagerInstance = GameObject.FindObjectOfType<startScreen_Manager>();
DontDestroyOnLoad(_startScreen_ManagerInstance.gameObject); // Unity dont delete this object on level load.
}
return _startScreen_ManagerInstance;
}
}
void Awake()
{
if(_startScreen_ManagerInstance == null)
{
_startScreen_ManagerInstance = this;
DontDestroyOnLoad(this);
}
else
{
if(this != _startScreen_ManagerInstance )
{
Destroy(this.gameObject);
}
}
}
First your singleton getter and Awake function are kinda duplicating itself. Secondly what are the buttons? are they childs of the gameObject your singleton was in? Its hard to tell without your full code (i.e. how you declare objects that are "not working". $$anonymous$$eanwhile I can tell you the problem I have once had, so I had a singleton in once scene that was having reference to buttons (which were childs of the same prefab). Singleton declaration is persistent across the scenes, even if you don't use "don't destroy on load", singleton will keep all the references to the object and the variables as it was initialized. So I was initializing my singleton, than loading next stage, than co$$anonymous$$g back to first scene, and when I wanted to use the button I was getting an error "gameobject you want to use has been destroyed". The thing was, when reloading scene the buttons were "recreated" but the singleton kept references to the old initial gameobjects. So to solve it I just cleaned the Instance in OnDestroy method, and on start I create new Instance which will than load references to current buttons. Other solution for that would be to make the button GameObjects to prefabs.
Thanks. I will try your idea. Am still confused with this singleton.
Answer by Mapleman · Apr 09, 2015 at 03:35 PM
For me your code looks overly complicated. Since in Unity scripts are attached to gameobjects, I assume that you have somekind of empty 'controller' gameobject which you would like to preserve between scene loads. So, in your scripts awake-method call:
DontDestroyOnLoad(gameObject); //gameObject is the reference to your controller GameObject which has the script (in this case startScreenManager) attached to
That's that. Because when you call inside Awake DontDestroyOnLoad(this), the this keyword actually points to your script. Well, it might be preserved (but probably not), but anyway the 'hosting' gameobject is destroyed and new one is created after scene load. And when new gameobject is created it's Awake method get's called. And since it's new object all it's fields and members are set to default values. Meaning that all references are null.
Thanks. Let me break down the hierarchy, I should have explained it better in my question, anyways.
I have a [empty]game object called game$$anonymous$$anager. Added a audio listener component and the script to it. Basically the script contains the function for the button [controls audio on and off]
Yes! You are right, am bit confused about this DontDestroyOnLoad(gameObject);
I used DontDestroyOnLoad(); But when the new scene is loaded everything get reset, So I thought probably singleton is the the one that I need to rely on.
Can you explain me what is the best way to keep the game object and all its component in the same state when the scene loads? Do I need to remove the awake lines? So, all the associated game components are active?
You shouldn't need to do anything to keep the states and references intact between scene loads as long as you are correctly calling the DontDestroyOnLoad(gameObject). Awake and Start are called only once when object is instantiated first time. And if the object doesn't get destroyed, then these methods won't get called again as long as the game session is running.
I did tried that. The problem is, I have attached audio component with audio enable/disable button. So when the scene loads if the user mute the sound and if he comes back again to the same scene, I want the button to remain muted and sound disabled. But the problem is again it restarts.
That's strange. I use exactly same kind of setup in my game, and it works like a charm. Are you absolutely sure that all objects taking part in your audio logic are contained within same gameobject?
Thanks. Yeah am quiet confused with this as well. I have a game object [Game $$anonymous$$anager] and audio component is only referenced through the script attached to this game object. No other game object is sharing the component. Also, when the user click the mute, the sprite is supposed to remain muted. But even though I add 'DontDestroy' Still everything resets on level change.