unity – How can I access a variable on a script in another scene that I made it dontdestroyonload?


I need to get access to the variable flag loading from some script in another scene.
The variable loading in my main menu scene and I need to access it in scripts in my game scene.

I’m not sure if using dontdestroyonload in this case is the right way and I don’t want to make the loading variable public static either :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEditor;
using Cinemachine;
using UnityStandardAssets.Characters.ThirdPerson;

public class MenuController : MonoBehaviour
{
    #region Default Values
    (Header("Default Menu Values"))
    (SerializeField) private float defaultVolume;
    (SerializeField) private int defaultSen;
    (SerializeField) private bool defaultInvertY;

    (Header("Levels To Load"))
    public string _newGameButtonLevel;
    private string levelToLoad;

    public SceneFader sceneFader;
    public GameObject player;

    private int menuNumber;
    #endregion

    #region Menu Dialogs
    (Header("Main Menu Components"))
    (SerializeField) private GameObject menuDefaultCanvas;
    (SerializeField) private GameObject GeneralSettingsCanvas;
    (SerializeField) private GameObject graphicsMenu;
    (SerializeField) private GameObject soundMenu;
    (SerializeField) private GameObject controlsMenu;
    (SerializeField) private GameObject confirmationMenu;
    (Space(10))
    (Header("Menu Popout Dialogs"))
    (SerializeField) private GameObject noSaveDialog;
    (SerializeField) private GameObject newGameDialog;
    (SerializeField) private GameObject loadGameDialog;
    #endregion

    #region Slider Linking
    (Header("Menu Sliders"))
    (SerializeField) private Text controllerSenText;
    (SerializeField) private Slider controllerSenSlider;
    public float controlSenFloat = 2f;
    (Space(10))
    (SerializeField) private Text volumeText;
    (SerializeField) private Slider volumeSlider;
    (Space(10))
    (SerializeField) private Toggle invertYToggle;
    #endregion

    public bool loading = false;

    #region Initialisation - Button Selection & Menu Order
    private void Start()
    {
        DontDestroyOnLoad(this);
        menuNumber = 1;
    }
    #endregion

    //MAIN SECTION
    public IEnumerator ConfirmationBox()
    {
        confirmationMenu.SetActive(true);
        yield return new WaitForSeconds(2);
        confirmationMenu.SetActive(false);
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (menuNumber == 2 || menuNumber == 7 || menuNumber == 8)
            {
                GoBackToMainMenu();
                ClickSound();
            }

            else if (menuNumber == 3 || menuNumber == 4 || menuNumber == 5)
            {
                GoBackToOptionsMenu();
                ClickSound();
            }

            else if (menuNumber == 6) //CONTROLS MENU
            {
                ClickSound();
            }
        }
    }

    private void ClickSound()
    {
        GetComponent<AudioSource>().Play();
    }

    #region Menu Mouse Clicks
    public void MouseClick(string buttonType)
    {
        if (buttonType == "Controls")
        {
            controlsMenu.SetActive(true);
            menuNumber = 6;
        }

        if (buttonType == "Graphics")
        {
            GeneralSettingsCanvas.SetActive(false);
            graphicsMenu.SetActive(true);
            menuNumber = 3;
        }

        if (buttonType == "Sound")
        {
            GeneralSettingsCanvas.SetActive(false);
            soundMenu.SetActive(true);
            menuNumber = 4;
        }

        if (buttonType == "Exit")
        {
            Debug.Log("YES QUIT!");
            Application.Quit();
        }

        if (buttonType == "Options")
        {
            menuDefaultCanvas.SetActive(false);
            GeneralSettingsCanvas.SetActive(true);
            menuNumber = 2;
        }

        if (buttonType == "LoadGame")
        {
            menuDefaultCanvas.SetActive(false);
            loadGameDialog.SetActive(true);
            menuNumber = 8;
        }

        if (buttonType == "NewGame")
        {
            menuDefaultCanvas.SetActive(false);
            newGameDialog.SetActive(true);
            menuNumber = 7;
        }
    }
    #endregion

    public void VolumeSlider(float volume)
    {
        AudioListener.volume = volume;
        volumeText.text = volume.ToString("0.0");
    }

    public void VolumeApply()
    {
        PlayerPrefs.SetFloat("masterVolume", AudioListener.volume);
        Debug.Log(PlayerPrefs.GetFloat("masterVolume"));
        StartCoroutine(ConfirmationBox());
    }

    public void ControllerSen()
    {
        controllerSenText.text = controllerSenSlider.value.ToString("0");
        controlSenFloat = controllerSenSlider.value;
    }

    #region ResetButton
    public void ResetButton(string GraphicsMenu)
    {
        if (GraphicsMenu == "Audio")
        {
            AudioListener.volume = defaultVolume;
            volumeSlider.value = defaultVolume;
            volumeText.text = defaultVolume.ToString("0.0");
            VolumeApply();
        }

        if (GraphicsMenu == "Graphics")
        {
            controllerSenText.text = defaultSen.ToString("0");
            controllerSenSlider.value = defaultSen;
            controlSenFloat = defaultSen;

            invertYToggle.isOn = false;
        }
    }
    #endregion

    #region Dialog Options - This is where we load what has been saved in player prefs!
    public void ClickNewGameDialog(string ButtonType)
    {
        if (ButtonType == "Yes")
        {
            // Here to use a script to load the start game scene slowly smooth fade to black
            // Then fade back to transparent when loading/loaded the scene game !!!!!
            //SceneManager.LoadScene(_newGameButtonLevel);

            // When making new game to reset everything state scene everythig.
            // Including the uiSceneText for example.
            // To check how to reset everything to default !
            loading = false;
            newGameDialog.SetActive(false);
            StartCoroutine(sceneFader.FadeAndLoadScene(SceneFader.FadeDirection.In, _newGameButtonLevel));
        }

        if (ButtonType == "No")
        {
            GoBackToMainMenu();
        }
    }

    public void ClickLoadGameDialog(string ButtonType)
    {
        if (ButtonType == "Yes")
        {
            //if (PlayerPrefs.HasKey("SavedLevel"))
            //{
            //Debug.Log("I WANT TO LOAD THE SAVED GAME");
            //LOAD LAST SAVED SCENE
            //levelToLoad = PlayerPrefs.GetString("SavedLevel");
            //SceneManager.LoadScene(levelToLoad);
            loading = true;
            newGameDialog.SetActive(false);
            StartCoroutine(sceneFader.FadeAndLoadScene(SceneFader.FadeDirection.In, _newGameButtonLevel));

            //}

            /*else
            {
                Debug.Log("Load Game Dialog");
                menuDefaultCanvas.SetActive(false);
                loadGameDialog.SetActive(false);
                noSaveDialog.SetActive(true);
            }*/
        }

        if (ButtonType == "No")
        {
            GoBackToMainMenu();
        }
    }
    #endregion

    #region Back to Menus
    public void GoBackToOptionsMenu()
    {
        GeneralSettingsCanvas.SetActive(true);
        graphicsMenu.SetActive(false);
        soundMenu.SetActive(false);

        VolumeApply();

        menuNumber = 2;
    }

    public void GoBackToMainMenu()
    {
        menuDefaultCanvas.SetActive(true);
        newGameDialog.SetActive(false);
        loadGameDialog.SetActive(false);
        noSaveDialog.SetActive(false);
        GeneralSettingsCanvas.SetActive(false);
        graphicsMenu.SetActive(false);
        soundMenu.SetActive(false);
        menuNumber = 1;
    }

    public void ClickQuitOptions()
    {
        GoBackToMainMenu();
    }

    public void ClickNoSaveDialog()
    {
        GoBackToMainMenu();
    }
    #endregion
}

At the top line 56 :

public bool loading = false;

Inside Start at line 61 :

DontDestroyOnLoad(this);

Then inside the method for starting a new game in line 207 :

loading = false;

And in the method that loading a saved game in line 228 :

loading = true;

Now that I know when it’s starting a new game and when it’s loading a game I want to use this loading variable in some scripts in my game scene.

For example this script :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class SceneFader : MonoBehaviour
{
    #region FIELDS
    public GameObject fadeOutUIGameobjectImage;
    public float fadeSpeed = 0.8f;

    private MenuController menuController;
    private Image fadeOutUIImage;

    private void Start()
    {
        
    }

    public enum FadeDirection
    {
        In, //Alpha = 1
        Out // Alpha = 0
    }
    #endregion

    #region FADE
    public IEnumerator Fade(FadeDirection fadeDirection)
    {
        fadeOutUIGameobjectImage.SetActive(true);

        float alpha = (fadeDirection == FadeDirection.Out) ? 1 : 0;
        float fadeEndValue = (fadeDirection == FadeDirection.Out) ? 0 : 1;
        if (fadeDirection == FadeDirection.Out)
        {
            while (alpha >= fadeEndValue)
            {
                SetColorImage(ref alpha, fadeDirection);
                yield return null;
            }
            fadeOutUIGameobjectImage.SetActive(false);
        }
        else
        {
            fadeOutUIGameobjectImage.SetActive(true);
            while (alpha <= fadeEndValue)
            {
                SetColorImage(ref alpha, fadeDirection);
                yield return null;
            }
        }
    }
    #endregion

    #region HELPERS
    public IEnumerator FadeAndLoadScene(FadeDirection fadeDirection, string sceneToLoad)
    {
        yield return Fade(fadeDirection);
        SceneManager.LoadScene(sceneToLoad);

        SceneManager.sceneLoaded += SceneManager_sceneLoaded;
    }

    private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
    {
        if (menuController.loading == true)
        {
            var saveLoad = GameObject.Find("Save System").GetComponent<SaveLoad>();
            saveLoad.Load();
        }
    }

    private void SetColorImage(ref float alpha, FadeDirection fadeDirection)
    {
        if(fadeOutUIImage == null)
        {
            fadeOutUIImage = fadeOutUIGameobjectImage.GetComponent<Image>();
        }

        fadeOutUIImage.color = new Color(fadeOutUIImage.color.r, fadeOutUIImage.color.g, fadeOutUIImage.color.b, alpha);
        alpha += Time.deltaTime * (1.0f / fadeSpeed) * ((fadeDirection == FadeDirection.Out) ? -1 : 1);
    }
    #endregion
}

At the top I did :

private MenuController menuController;

Then inside the event SceneManager_sceneLoaded I did at line 67 :

if (menuController.loading == true)

but I didn’t make any reference to the MenuController script even if it’s not destroyed.
so loading will be null here I guess.

The idea is to use global in my project with the loading bool flag variable to find if the game is loading or if a new game started.