0
\$\begingroup\$

In a game I'm working on, I have a button on the pause menu that allows me to mute and unmute the background music. The toggle button, in the inspector, references the audio manager object and calls the function to update the sound when the button is pressed. This worked well until recently when I made my audio manager persist across all scenes to avoid the music restarting between levels. As a result, when the next scene loads, the audio manager cannot be found by the toggle button (which I would ordinarily have to drag into the toggle button's "On Value Changed" field from the inspector.

Is there a way around this, or am I going to have to make my pause menu persist across all scenes, too? If I do this, then how should I handle scenes like the main menu or game over menu when they don't have pause menu objects?

\$\endgroup\$
4
  • \$\begingroup\$ To clarify, I made my audio manager persist across all scenes by using the Don'tDestroyOnLoad function. \$\endgroup\$ Jun 11 at 1:19
  • \$\begingroup\$ You can make your music manager singleton. Then your OnValueChanged unity event can call a method that is part of a component on the same game objects as the button. This method subsequently calls the music manager singleton. \$\endgroup\$
    – Nikaas
    Jun 11 at 7:40
  • \$\begingroup\$ This may be related: in-unity-how-do-i-correctly-implement-the-singleton-pattern \$\endgroup\$
    – Mangata
    Jun 11 at 7:58
  • \$\begingroup\$ This will help you probably: docs.unity3d.com/ScriptReference/…. \$\endgroup\$ Jun 14 at 6:26

1 Answer 1

0
\$\begingroup\$

Use a relay:

public class MenuFunctions() {

    // If your AudioManager is already a singleton with an AudioManager.Instance getter,
    // you can use that instead of finding & caching your own reference.
    AudioManager _audio;

    public Toggle _muteButton;

    void Start() {
        // On load, cache a reference to the dependencies persisted from the old scene.
        _audio = FindObjectOfType<AudioManager>();

        // Do any setup needed to ensure the displayed menu state matches any
        // persistent state inherited from the previous scene.
        _muteButton.SetValueWithoutNotify(_audio.isMuted);
    }

    // Your mute button in this scene calls this method.
    public void ToggleMute() { 
        // ...which then forwards the message along to the real recipient.
        _audio.ToggleMute(); 
    }
}

Put this script on your pause menu, and wire it up so your mute button (and any other buttons with dependencies on stuff not in the scene) sends its interactions through this script instance.

At runtime, it will get the correct reference to route those interactions along to the correct recipient that did not exist at edit time.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .