Reloading the scene keeps "Don't destroy on load" objects

Hi,

I’m reloading a scene using

public void RestartScene()
{
     Scene scene = SceneManager.GetActiveScene();
     SceneManager.LoadScene(scene.buildIndex, LoadSceneMode.Single);
}

The problem is that I have a couple of items which have been marked as “Don’t destroy on load”, and they get duplicated every time the scene is loaded.

How can I prevent this?

1 Like

It’s you marked them don’t destroy on load, so they are not destroyed when loading any scene. There are different ways of preventing it. You may create those objects from prefab during awake if they are not exists. You can create separate loader scene with those objects only and never load it again (althrough you should load it in the editor if any scene started except this. Also it is okay to create a static variable, fill it at first launch and destroy self if it is already not null.

1 Like

There’s various flavors of a “UnitySingleton” class sprinkled all over the internet. Most of them should do what you want, making sure there’s only one thing. Google around and study how they work to make sure they sequence things the way you need them to.

1 Like

Something simple like this should work:

public class YourScript: MonoBehaviour {
private static YourScript instance;
void Awake() {
if (instance != null && instance != this) {
Destroy(gameObject);
}
else {
instance = this;
}
}
//the rest of your code
}
4 Likes

What @StarManta posted is awesome because there is very little where it can go wrong. Simplicity for the win!

But keep in mind that technically that is not going to persist through a scene load. I call the above code a “Scene Singleton,” which will persist only until the next full scene reload. They are SUPER useful for things that only need to persist through a level.

If you want it to be a true forever-singleton, then put this in around line 8 above:

DontDestroyOnLoad( transform.root);

Adding .root is important if you hang this in a scene and it isn’t at the root. Calls to mark non-root GameObjects as DontDestroyOnLoad() will fail.

Thank you, this works nicely! (with the ( transform.root) added)

I was using another one (the one shared below) that was causing the objects with the script attached to it to duplicate.
Maybe somebody can point out why that happens

public class DontDestroy : MonoBehaviour
{
    //[HideInInspector]
    public string objectID;


    private void Awake()
    {
        objectID = name + transform.position.ToString() + transform.eulerAngles.ToString();
    }


    void Start()
    {
        var dontDestroyObjects = Object.FindObjectsOfType<DontDestroy>();

        for (int i = 0; i < dontDestroyObjects.Length; i++)
        {
            if (dontDestroyObjects[i] != this && dontDestroyObjects[i].objectID == objectID)
            {
                Destroy(gameObject);
            }

        }
        DontDestroyOnLoad(gameObject);
    }
}

Worked perfectly

I feel like I’m not understanding something. If instance is already assigned when Awake is called then it’s because the scene has been loaded before, right? If it’s not marked as DontDestroyOnLoad, wouldn’t it already be destroyed when the scene loads again? In what case would you need to destroy it yourself?

If you ever find yourself asking “is this instance null?” then you are working with a defective singleton.

It doesn’t matter if you saw it in a tutorial: it is defective if it meets the above criteria.

Delete it and make one that plays nice with Unity3D. Here’s how:

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

Alternately you could start one up with a [RuntimeInitializeOnLoad] attribute.

There is never a reason to drag a GameObject into a scene if it will be DontDestroyOnLoad.

If you do:

  • you may drag it into something else that isn’t DDOL. FAIL
  • you may drag something else into it that isn’t DDOL. FAIL

Just DO NOT drag anything into a scene that will be marked DontDestroyOnLoad. Just Don’t Do It!

1 Like