0
\$\begingroup\$

I have two scenes: "Main Menu" and "Game."

When running the game it starts with the Main Menu scene loaded. Then, when starting a new game the Main Menu scene is unloaded and the Game scene is loaded. However, even if the Game scene is loaded it keeps showing the Main Menu scene in the name:

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

public class AudioManager : MonoBehaviour
{
    public GameObject gameAudio;

    private AudioSource audioSource;
    private string sceneName;
    private bool currentScene = false;

    void Awake()
    {
        DontDestroyOnLoad(transform.gameObject);
    }

    // Start is called before the first frame update
    void Start()
    {
        // Create a temporary reference to the current scene.
        Scene currentScene = SceneManager.GetActiveScene();

        // Retrieve the name of this scene.
        sceneName = currentScene.name;

        audioSource = gameAudio.GetComponent<AudioSource>();

        var mainmenumusic = GameObject.Find("Main Menu Settings");
        audioSource.volume = mainmenumusic.GetComponent<AudioSource>().volume;
    }

    // Update is called once per frame
    void Update()
    {
        if (sceneName == "Game" && currentScene == false)
        {
            audioSource.Play();
            currentScene = true;
        }
        else
        {
            if (sceneName != "Game")
            {
                audioSource.Stop();
                currentScene = false;
            }
        }
    }

    //Called when Slider is moved
    public void changeVolume(float sliderValue)
    {
        audioSource = gameAudio.GetComponent<AudioSource>();
        audioSource.volume = sliderValue;
    }
}

During Update, even if the Game scene has loaded (and only the Game scene is loaded) sceneName is still set to "Main Menu":

if (sceneName == "Game" && currentScene == false)

sceneName is never "Game."

And a side question:

When I press the escape key back to the main menu it keeps creating the DontDestroyOnLoad object over and over again. How can I avoid creating the DontDestroyOnLoad all the time? This script is in my Game scene:

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

public class BackToMainMenu : MonoBehaviour
{
    public GameObject[] objsToDisable;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (Time.timeScale == 0)
            {
                DisableEnableUiTexts(true);
                SceneManager.UnloadSceneAsync(0);
                Cursor.visible = false;
                Time.timeScale = 1;
            }
            else
            {
                Time.timeScale = 0;
                MenuController.LoadSceneForSavedGame = false;
                SceneManager.LoadScene(0, LoadSceneMode.Additive);
                SceneManager.sceneLoaded += SceneManager_sceneLoaded;

                Cursor.visible = true;
            }
        }
    }

    private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
    {
        DisableEnableUiTexts(false);
    }

    private void DisableEnableUiTexts(bool enabled)
    {
        foreach (GameObject go in objsToDisable)
        {
            if (go.name == "Cameras")
            {
                foreach(Transform child in go.transform)
                {
                    if(child.name == "Main Camera")
                    {
                        if (enabled == false)
                        {
                            child.GetComponent<Camera>().enabled = false;
                        }
                        else
                        {
                            child.GetComponent<Camera>().enabled = true;
                        }
                    }
                }
            }
            else
            {
                go.SetActive(enabled);
            }
        }
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ Can you boil this down to a minimal example that demonstrates your problem? It looks like you have quite a lot of code here unrelated to loading a scene and checking its name. \$\endgroup\$
    – DMGregory
    Jan 19 at 10:36
0
\$\begingroup\$

To answer your side question first, You are trying to create a persistent class and for that what you can do is:

using UnityEngine;

public class UnitySingletonPersistent<T> : MonoBehaviour where T : Component
    {
        private static T instance;

        public static T Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = FindObjectOfType<T>();
                    if (instance == null)
                    {
                        var obj = new GameObject {hideFlags = HideFlags.HideAndDontSave};
                        instance = obj.AddComponent<T>();
                    }
                }

                return instance;
            }
        }

        public virtual void Awake()
        {
            DontDestroyOnLoad(gameObject);
            if (instance == null)
            {
                instance = this as T;
            }
            else
            {
                Destroy(gameObject);
            }
        }
    }

Now inherit from this like:

public class AudioManager : UnitySingletonPersistent<AudioManager>
{
   //Remove awake from here you don't need Don't Destroy On Load here.
}

Now towards your main question. The problem is that you are getting SceneManager.GetActiveScene() in the Start() which is why when in Update when even scene changes you don't have updated scene name.

Try Checking name like:

if (SceneManager.GetActiveScene().name == "Game" && currentScene == false)
{
   //Your rest of the code
}

OR you could update your currentScene variable every time you change the scene instead of doing that only once.

public void Start()
    {
        SceneManager.activeSceneChanged += ChangedActiveScene;
    }

private void ChangedActiveScene(Scene current, Scene next)
    {
        string currentName = current.name;

        if (currentName == null)
        {
            // Scene1 has been removed
            currentName = "Replaced";
        }

        Debug.Log("Scenes: " + currentName + ", " + next.name);
    }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.