- Home /
DontDestroyOnLoad duplicates GameObjects
Hello.
I have a strange problem with DontDestroyOnLoad. I have some kind of map as a starting scene. From there there user can click on certain map-objects and a new level is loaded with Application.LoadLevel(). When the level is finished the map is loaded again.
I have a prefab for my global data. It is a hierarchy of several GameManagers und DataObjects that are needed in every scene. The hierarchy looks like this in design-time: ![alt text][1]
The root GameObject 'GlobalData' has a script attached that calls DontDestroyOnLoad:
using UnityEngine;
using System.Collections;
public class GlobalData : MonoBehaviour
{
void Awake()
{
DontDestroyOnLoad(this.gameObject);
}
}
As far as I understood the docs all child gameobjects should not be destroyed, too.
After starting the game and playing some levels (with jumping back to the map) the hierachy looks like this during runtime: ![alt text][2]
Somehow the prefab is added again and again but the manager-objects are missing. [1]: /storage/temp/54720-001.jpg [2]: /storage/temp/54721-003.jpg
Another issue is that DontDestroyOnLoad does not seem to work in general as when I'm doing some debug prints the Start and Awake methods of my manager-objects are called for every scene.
Has anybody an idea what is going wrong here?
Answer by MewEight · Sep 21, 2015 at 11:53 AM
The problem is that you are loading a scene with that object in. If I am not mistaken, for example:
Scene 1 - Have your data object
You click and load Scene 2
You go back to Scene 1
Duplicated data object because Scene 1 has your data object
You might want to try using Singleton. A simple implementation
public class CharacterManager : MonoBehaviour
{
public static CharacterManager instance;
void Awake()
{
if (instance == null)
{
instance = this;
}
else
{
Destroy(this.gameObject);
return;
}
}
}
Hope this helps.
I changed my script and I got rid of the duplicates but I still have the problem that a child gameobject is recreated everytime I get back to my map.
This is the current setup: 1. In scene one I have the Singleton GlobalData. 2. In scene two GlobalData is added automatically thanks DontDestroyOnLoad(). 3. Going back to scene one the _Cart$$anonymous$$anager is recreated as its Awake() and Start() methods are called.
Any Idea why this happens?
I am not really clear on your situation, did you manage to destroy the main parent gameobject? or is it still duplicating? or, its just that the _Cart$$anonymous$$anager is still calling Awake and Start?
The main parent gameobject is doing fine now. No duplicating anymore.
But the _Cart$$anonymous$$anager calls its Awake() and Start() methods everytime I go back to my map (starting scene) but not in the levels. It seems that going from scene 1 > 2 works but going back from 2 > 1 seems to recreate the _Cart$$anonymous$$anager.
This is the singleton of the parent gameobject:
void Awake()
{
if(_instance == null)
{
_instance = this;
DontDestroyOnLoad(this.gameObject);
}
else
{
if(this != _instance)
Destroy(this.gameObject);
}
}
As far as I understand I only need one singleton and DontDestroyOnLoad() on the parent gameobject in this setup and this is what I've got.
The _Cart$$anonymous$$anager is whether a singleton nor does it call DontDestroyOnLoad()
Is the _Cart$$anonymous$$anager needed along all the scenes? If not might as well remove it from the singleton parent objects. If yes, then I would recommend making it an object itself and making it a singleton as well.
As to prevent the Start function to running, what i usually do is just a boolean check if
if( instance != this)
_skipStart = true
the cartmanager is recreated because your Scene one has it. To prevent this you can load a scene similar to the scene one but without the singletons.
Ahh, you are right :). The GlobalData-Singleton is created and destroyed. So its children are created and destroyed, too. I should had hit on that by myself :).
So everything is working as expected. Thanky you!
Answer by MNM123 · Sep 21, 2015 at 11:47 AM
perhaps you can use this.
public void Awake()
{
DontDestroyOnLoad(this);
if (FindObjectsOfType(GetType()).Length > 1)
{
Destroy(gameObject);
}
}
if there are more than one existing objects of this type, then it will destroy the other.. search singletons and you can find a lot of stuff on this.
hope this helps.
Hi, I came across with this kind of situation .I handled it by using below steps.
1.Instantiate the game objects like maps etc in your initial scene by using below code Instantiate objects that should be available across your game play(may be you can Setactive true/false based on game requirement)
void Start(){
if(GameObject.Find("$$anonymous$$ap") == null)
{
$$anonymous$$ap=(GameObject) Instantiate (Resources.Load("$$anonymous$$ap"),vector3.zero,quaternion.identity);
$$anonymous$$ap.name = "$$anonymous$$ap";
}
}
2.Also make sure to attach the below code to the objects that were instantiated in the above step
void Awake()
{
DontDestroyOnLoad(this);
}
Hope this may help you at very basic level. Nsks
Answer by Tom163 · Mar 21, 2018 at 06:38 PM
Here is the workaround I use all the time:
My first scene is called "Loader" - it contains all the persistent (dontdestroyonload) gameobjects for my game.
The only thing it does is load the main menu. Since I never return to this scene, no duplicates.