How do I Use The Scene as a Variable

Hello, I am having some problems with the Unity Engine. I followed BlackThornProd’s video on keeping music on different scenes, but I don’t want the music to play in all the scenes, I just want to keep the music playing on the Start and Options menu, but I can’t seem to get the scene as a variable. I tried changing a string variable in the menu script each time I load a scene, but it just said that I can’t get the direct reference (maybe it’s just because it’s static?) anyway, I decided to post this, so if anyone knows the answer, please give help. This is my code:

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

public class Music : MonoBehaviour
{
   private static Music instance;
   
   void Awake()
   {
       if (instance == null)
       {
           if(SceneManager.GetSceneByName("Scene Name") == "StartMenu" || 
           SceneManager.GetSceneByName("Scene Name") == "Options Menu")
           {
                instance = this;
                DontDestroyOnLoad(instance);
           }
       }
       else
       {
           Destroy(gameObject);
       }
   }
}

What you’re doing is:

  • There is a GameObject in a scene.
  • When the scene starts, that object checks if there’s already an instance of itself for that pseudo-singleton pattern.
  • If there isn’t, it finds a scene called “Scene Name” (!) and compares that scene info with a string (!).
  • If that comparison is successful, it registers itself as the pseudo-singleton instance and prevents itself from getting destroyed.

So this means that

  • You’re not checking which scene you’re in, you’re grabbing some scene from the scene list via name.
  • You’re not making the existing Music component check anything when the scene changes (Awake is only called once per object, and if that object survives a scene change, it’s not called again).

What I assume you’re trying to do is to check which scene the Music component is in each time a new scene is loaded. This can be done using SceneManager.activeSceneChanged.

private void Awake()
{
  if (!instance)
  {
    instance = this;
    DontDestroyOnLoad(this);
    SceneManager.activeSceneChanged += OnSceneChange;
  }
  else
  {
    Destroy(gameObject);
  }
}

private void OnSceneChange(Scene current, Scene next)
{
  if (next.name == "StartMenu")
  {
    // keep playing
  }
  else
  {
    // stop playing
  }
}

As you can see, the next scene is passed as an argument to the method, so we don’t need to call SceneManager.GetActiveScene (which would otherwise have been what you were looking for).

This works, but let me add that this is a bit of bad style; as an example, if someone else in your team (or you in the future) didn’t know (or forgot) that this script depended on scenes being named in a precise way, scene names could be changed and that code would silently break. This is a good recipe for hard-to-find bugs.

I’d recommend to instead place a GameObject in your menu and options scenes that indicate that a specific music should be played. In the OnSceneChange method, you can use something like FindObjectOfType to find the music-to-play component in that scene, and if you find none, you can stop playing. This adds a bit of robustness to your code, which then is less likely to break as the project evolves.