How Volume Persistence Works

On startup, SoundManager reads every saved AudioMixer parameter from the save file and applies it to the mixer automatically. When the player moves a slider, GameOptionsMenu_SoundSlider calls SoundManager.Set(), which updates the mixer and writes the new value to disk immediately. Parameters not yet saved keep whatever default value was set in the AudioMixer asset.

Setting Up a Volume Slider

  1. Expose the parameter in your AudioMixer
    Open your AudioMixer asset. Right-click the volume knob of the group you want to control and select Expose to script. In the Exposed Parameters list at the top, rename it clearly (e.g. MusicVolume).
  2. Add a UI Slider to your canvas
    Set Min Value to −80 and Max Value to 0. This maps the slider range to the decibel range of the AudioMixer volume parameter.
  3. Add GameOptionsMenu_SoundSlider to the Slider's GameObject
    The component requires a Slider on the same object — Unity will warn you if it's missing.
  4. Configure the component in the Inspector
    Assign the AudioMixer asset and set Parameter Name to the exact exposed parameter name (case-sensitive).
  5. Wire OnValueChanged
    In the Slider's OnValueChanged event, add an entry pointing to GameOptionsMenu_SoundSlider.SetValue (dynamic float).
  6. Ensure SoundManager is in the scene
    The SoundManager prefab must be present (or loaded via DontDestroyOnLoad) with the same AudioMixer assigned. If it is missing, Set() will throw a null reference.
💡
First launch On first play, the slider reads its position from the mixer asset's default value via AudioMixer.GetFloat(). After the player moves it for the first time the value is saved and restored on every subsequent session.

Setting Up Scene Music

  1. Add the MusicManager prefab to each scene that needs background music.
  2. Assign the AudioSource, the AudioClip for that scene, and set Transition Duration (default 1 second).
  3. When the scene loads, MusicManager checks whether the same clip is already playing:
    • Same clip → the new manager is destroyed, music continues uninterrupted.
    • Different clip → crossfade begins on the existing manager, then the new one is destroyed.
    • No manager exists → the new one becomes the singleton and starts playing.
⚠️
DontDestroyOnLoad MusicManager calls DontDestroyOnLoad on itself. Do not place it as a child of another DontDestroyOnLoad object — Unity does not support nested DontDestroyOnLoad hierarchies.

Playing Sound Effects from Instructions

Inside any Tick(ExecutionContext ctx), play a sound through the player's AudioSource:

protected override IEnumerator Tick(ExecutionContext ctx)
{
    ctx.player.PlaySound(mySoundResource);
    // ... rest of instruction logic
    yield return new WaitForSeconds(1f);
}

PlaySound stops any currently playing clip on the player's source before starting the new one, so calls do not stack.