Issues with Data over Scenes, and DontDestroyOnLoad

Greetings and salutations.
I was hoping to find some help here on the forums, I am a fairly new Unity user and coder in general and currently stuck on a huge problem in my first “owngame”.

My current issue, that I am ashamed to admit I have been working on the last nine and a half hours, is that I could not figure out how to retain my data when loading a new scene.

Eventually I tried the “DontDestroyOnLoad” on my LevelManager script/object, and it seemed to work. Allthough the canvas did not communicate with my levelmanager. So then I made a uiscript, and gave that a dontdestroyonload, as well.

The data storage seemed therefor to be fixed, but… now on level 2. My Player, camera and other colliders will not communicate with the “DontdestroyOnLoad” scene. I was hoping I might get a pointer or two on how to fix / optimize this. :slight_smile:

I will post my code in hasteBin to avoid a terribly long post. Also pictures of the level hierarchy in game.

LevelManager Script - https://hastebin.com/zegaqurizo.cs
UI Manager Script - https://hastebin.com/awurerizuk.cs


You need to look up what a Singleton pattern is and use that pattern on your managers. Then all things can talk to singletons and you’ll never need to reconnect things.

Edit:

Additional Reading:

Hey thanks for the quick reply.

I thought this was the Singleton pattern?

    public static LevelManager StaticLM;

    public void Awake()
    {
        if (StaticLM == null)
        {
            DontDestroyOnLoad(gameObject);
            StaticLM = this;
        }
        else if (StaticLM != this)
        {
            Destroy(this.gameObject);
        }

Yep.

But are your other scripts using the StaticLM variable to access the manager?

No, I made a new one on the UI Manager

    private void Awake()
    {
        if (staticCanvas == null)
        {
            DontDestroyOnLoad(this.gameObject);
            staticCanvas = this;
        }
        else if (staticCanvas != this)
        {
            Destroy(this.gameObject);
        }
    }

And there is nothing on the rest of them.

How would you go about accessing it? How can I make the singleton communicate with all my scripts. The concept just beyond me atm. :slight_smile:

Oh right, your level manager has a reference to the player, and the player is being destroyed on scene load and a new one is being created hence the reference gets set to null.

You’ll need to reconnect those in code.

You currently set up those references in Start() but Start will only be called once when the singleton manager is created and not when the new manager in the loaded scene is created (To clarify: it will get called on the new manager but that’s not the same object as the one you’ve assigned to StaticLM). you could do this:

Awake()
{
  if( StaticLM == null )
  {
    StaticLM = this; // setup the singleton
    // now wait for Start() to initialise
  }
  else
  {
    StaticLM.Start(); // reinitialise with new scene objects
    DestroyImmediate(gameObject);
  }
}

I really appreciate your help, but I’ve got to admit that I don’t really follow. How would I go about to setup the singleton in the if statement there? I added the StaticLM.start(); but not really sure what comes after.

I also tried to do a “LevelManager.StaticLM();” in the playermovement and camera script. But that didn’t really work.

https://hastebin.com/hecocevaho.cs - player script.

When I move data between scenes, I prefer to just slap a unique tag onto the gameobject, put dontdestroyonload on that gameobject, and setup references to that gameobject in the new scene on enable, awake, or start with a FindGameObjectWithTag call. Super easy.

I only create that gameobject in a single place, so I’m not too worried about duplicates. Usually it is in an intro scene that only ever runs once. If I create the object in a scene that is run multiple times, then I just add a check for if a gameobject already exists with that tag before I instantiate a new one.

Awake()
{
  if( StaticLM == null )
  {
    StaticLM = this; // setup the singleton
    // now wait for Start() to initialise
  }
  else
  {
    StaticLM.Start(); // reinitialise with new scene objects
    DestroyImmediate(gameObject);
  }
}

This code goes in your LevelManager script. It basically gets the new level manager object that is created when you load a new scene to call Start on the first level manager created in your game (the singleton / StaticLM) so that the Start function as shown in the code you attached can reconnect the gameobjects it needs to work properly (Player, etc.).