C# - SceneManager.LoadScene does NOT reset all variables?

Hi everyone,

I added a button in my game, and if you click it, it reloads the level. * SceneManager.LoadScene(sceneName);*

However,

I realized it does not Reset all scripts etc. I does reload the scene, but a bunch of the variables on other scripts are not being reset?

What do I do/Look for. To Reset everything in the scene as if it was the first time I opened it (including the other scripts)
Thank you!

It really is hard to guess what isn’t being reset with no code. In general, any static variables, or objects marked as DontDestroyOnLoad() will stick around, and will not reset.

You’ll have to use the OnLevelWasLoaded callback to reset those manually.

2 Likes

Are you using statics to record mutable game state? This is a bad idea, for reasons you have just discovered. Resetting statics is a pain.

You should only use statics for state that is truely constant throughout the life of your program. Or for stateless functions.

1 Like

Except for where you specifically tell it not to, it destroys all scripts and loads new instances of them. Past that, I can only agree with what the others have already said, and suggest getting a better understanding of how static variables work (and where they should/shouldn’t be used) if you are indeed using them.

To have a static, I have to have written “static” , theres not other words that can also make something static, right?

Since I dont use static anywhere, nor do I use “dontDestroy…”

How about you give us an example of an object or script that isn’t being “reset”?

1 Like

This script works at the start, but once I reload my level it doesnt work again.

voidStart()
{
if(amountCC<=0)
  {
   Debug.Log("Add # of TileColor in AmountCC");
   enabled=false;
  }
}

void OnTriggerEnter( Collider other )
    {
        GameObject[] tiles = GameObject.FindGameObjectsWithTag("TileColor");

        int count = 0;
        foreach( GameObject t in tiles )
        {
            ChangeColor cc = t.GetComponent<ChangeColor>();
   
            if ( !cc.isBlack )
                break;
            else
                count++; // add one to our count if it is black
        }

        if ( count == amountCC )
        {
            Invoke ("WinFreeze", delayLoad);
            print("=============THE END IS WORKING=============");
        }
    }

This is the Reload Level Script, which works to load normal scenes back and forth like menu to options to credits etc.

    public        string         sceneName;                   
    public         float         delayLoad;   
             
    void Start ()
    {
        Time.timeScale = 1;
        Invoke ("LoadedLevel", delayLoad);               
    }   

    void LoadedLevel()
    {
        SceneManager.LoadScene (sceneName);                
    }

… isn’t the whole script. We can only base our help on the information you make available.

Well, the only part on top is

using UnityEngine;
using System.Collections;
using MadLevelManager;

public class endCheck : MonoBehaviour
{

    public float delayLoad = 0.5f;
    public int amountCC;

and at the bottom:

void WinFreeze() {
        Time.timeScale = 0.01f;
    //    gameObject.GetComponent<PlayerOneController> ().enabled = false;
        print (" ============= THE END IS WORKING ============= ");

    }
}

Thought these to parts are pretty irrelevant (even when Time.timeScale = 1 it doesnt work)

Yes, they are irrelevant, but how were we meant to know that without knowing what’s in them?

At any rate, you have public variables in there. Are you certain that they aren’t being accessed or modified from elsewhere? (You can mark them as [SerializeField] and private to make them accessible via the Inspector but also ensuring that other code can’t directly mess with it.)

Maybe you are expecting gameobjects to always get value of the prefab when game starts? It’s easy to make a mistake that you change some value for a test in gameobject, to override prefab. Then you change prefab’s to some other value, but your scene’s object still has the overriden value set to it. If that’s the case the value will show up in inspector as bolded. You can fix those by right clicking the name and select “revert to prefab value”.

I know that this post is years old, but I was wondering how would you suggest that I hadle game states, because Im doing exactly that (using static fields ) and Im having the same issue (I need to access these fields from other scripts by the way…)