How can I control the volume of the music and the sound effects seperately with two sliders?

How can I control the volume of the music and the sound effects seperately with two sliders?

In the Hierarchy i have one Main Camera with Audio Listener.
In the Hierarchy I have AudioPanel and two child Sliders.

And the AudioManager script that attached to the AudioPanel:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using System.Linq;


[System.Serializable]


public class AudioManager : MonoBehaviour
{

    public Slider musicVolume;
    public Slider effectsVolume;

    private void SetMusicListenerVolume()
    {
        AudioListener.volume = musicVolume.value;
    }

    public void ApplyMusicSettings()
    {
        SetMusicListenerVolume();
    }

    private void SetEffectsListenerVolume()
    {
        AudioListener.volume = effectsVolume.value;
    }

    public void ApplyEffectsSettings()
    {
        SetEffectsListenerVolume();
    }
}

Now in the Hierarchy I have some Audio Sources components for the sound effects and I want to control them with the Slider (1).
And to control the music sound with the Slider.
The music sound have his own Audio Source.
The problem is that the AudioListener in the script control all the Audio Sources. Music and Effects. Or maybe only the Music ? U'm not sure.
But when i change both sliders when the game is running it's changing the music volume.
My question/s is how to control with Slider only the volume of the music and with Slider (1) the effects volume ?
And how can i get all the effects audio sources in the script and control the volume of them using the Slider (1) ?
The audio source component of the music is attached to GameObject name Sound.
All the other audio sources components are effects and are in some places in the Hierarchy.

Solutions/Answers:

Answer 1:

You will need to use an audio mixer.

An audio mixer lets audio sources specify which group they should output to, so you should create two groups, one for sounds effects, and one for music. You need to then expose the attenuation (volume) parameter of each group to code. Then, the music audio source can specify that it should play through the music group, and all the others play through the sound effects group.

Then, in code, you need to get a reference to the audio mixer (for example by adding a reference in a Monobehaviour and assigning it in the inspector) and set the volume of individual groups using the names of the parameters when they were exposed from the inspector.

Note that the range of attenuation is -80 (muted) to 0 (full volume). And it’s not linear, so the slider won’t control the volume smoothly if you just map the volume directly from the slider to attenuation value. You will need to do a conversion using mixer.SetFloat(parameterName, Mathf.Log10(sliderValue) * 20); to get it nice and smooth (assuming sliderValue ranges from 0 to 1). See here for more details.

Note: audio sources created in the editor should be assigned to groups in the inspector. To assign an audio source created at runtime to the correct group via code, use AudioSource.outputAudioMixerGroup

Answer 2:

If all you want is to control the music and sfx volumes through separate sliders, then your AudioManager just needs a few simple changes. πŸ™‚

public class AudioManager : MonoBehaviour
{

    public Slider musicVolume;
    public Slider effectsVolume;

    // Make sure to plug these in in the inspector.
    public AudioSource musicPlayer;
    public AudioSource effectsPlayer;

    private void Start()
    {
        /*
        All sliders have an onValueChanged event that executes every time the sliders' values are 
        changed (meaning whenever their knobs are moved).

        By hooking them up to the appropriate volume-changing functions (which I added float 
        parameters to, out of necessity), the volumes of the audiosources change with them. 
        */

        musicVolume.onValueChanged.AddListener(SetMusicListenerVolume);
        effectsVolume.onValueChanged.AddListener(SetEffectsListenerVolume);

    }

    private void SetMusicListenerVolume(float volume)
    {
        musicPlayer.volume = volume;
    }

    private void SetEffectsListenerVolume(float volume)
    {
        effectsPlayer.volume = volume;
    }

    public void ApplyMusicSettings()
    {
        // The volume updates itself through the slider's events, so no need to update 
        // the volume in this function.
        //SetMusicListenerVolume();
    }

    public void ApplyEffectsSettings()
    {
        // Or this one.
        //SetEffectsListenerVolume();
    }
}

The comments explain everything.

References