Simple Volume Control System

Audio is a crucial part of the process of making a game, but do you know how to use Audio Mixer to control the volume of your game?

What is cool about the Audio system in Unity is that you can assign Audio Sources to the Audio Mixer Groups.

This is pretty handy especially as you don’t have to all Audio Sources on the scene to change the volume.

What is Audio Mixer? ?

Before we jump into making our volume controls, let’s talk about Audio Mixer and what it is.

Audio Mixer in Unity Editor

In short, Audio Mixer is part of the Unity Audio system, which can output and mix different sounds and can apply sound effects to them.

In the Audio Mixer, you can control many parameters. Volume, effect, pitch, etc. All the things you might want to play with.

The idea ?

Okay, so the question is, how can we build a volume control system?

We will need to assign an output group to each Audio Source. With that, we will be able to control volume for all elements in the group in one place. ?

It will be something quite easy to make, believe me, or not. ?

Preparing ?‍?

In the beginning, we will have to create an Audio Mixer for our project.

Creating a new Audio Mixer asset.

Now you have to double click on newly created Audio Mixer.

Double click to open Audio Mixer Window.

In the next step, we will create two mixer groups. One will be for music and another one for sounds.

Create mixer groups for Music and Sound.

Great! Now we have to expose the volume of both groups. To do that, you have to select a group, right-click on the Volume and click Expose.

Select new group.
Expose Volume parameter.

With volume exposed, now we can change names of parameters to something more meaningful, like “Music Volume” and “Sound Volume”.

Rename exposed parameters.

And that’s the preparation of the Audio Mixer for our Simple Volume Control System.

With that done, now we can simply assign the output of Audio Source to one of our two groups.

Assign output of Audio Source to one of the groups.

Coding ?‍?

To control our volume, we have to make a really simple script that has a reference to the Audio Mixer and changes the exposed volume parameter in it.

using UnityEngine;
using UnityEngine.Audio;

/// <summary>
/// Audio controller.
/// Changes volumes of different audio groups.
/// </summary>
public class AudioController : MonoBehaviour
{
    // Reference to the master audio mixer.
    [SerializeField]
    private AudioMixer masterMixer;

    // Parameters names.
    private const string SOUND_VOLUME_KEY = "Sound Volume";
    private const string MUSIC_VOLUME_KEY = "Music Volume";

    /// <summary>
    /// Changes volume in master mixer.
    /// </summary>
    /// <param name="volume">Sound Volume. Values: 0.0001 - 1</param>
    public void ChangeSoundVolume(float volume)
    {
        // Converting volume from linear to a logarithmic scale.
        volume = Mathf.Log(volume) * 20;
        masterMixer.SetFloat(SOUND_VOLUME_KEY, volume);
    }

    /// <summary>
    /// Changes volume in master mixer.
    /// </summary>
    /// <param name="volume">Music Volume. Values: 0.0001 - 1</param>
    public void ChangeMusicVolume(float volume)
    {
        // Converting volume from linear to a logarithmic scale.
        volume = Mathf.Log(volume) * 20;
        masterMixer.SetFloat(MUSIC_VOLUME_KEY, volume);
    }
}

You might notice that I’m converting volume value. This is because the audio volume is measured not in linear but on a logarithmic scale.

I’m also expecting that I should receive values between 0.0001 and 1.0, which makes everything easier… ?

Example ?‍♂️

Let’s build a simple Audio Settings View on the scene. We will need sliders for music and sound volume control. On top of that, let’s add a button that will make a clicking noise and music playing in the background.

Audio Settings View.

This looks nice to me! ?

Now we need a simple View class for it! Like in MVC!

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;

/// <summary>
/// UI Audio Settings view.
/// </summary>
public class UIAudioSettings : MonoBehaviour
{
    // Reference to sound volume slider.
    [SerializeField]
    private Slider soundSlider;
    // Action called when sound volume is changed.
    public UnityAction<float> OnSoundVolumeChanged;

    // Reference to music volume slider.
    [SerializeField]
    private Slider musicSlider;
    // Action called when music volume is changed.
    public UnityAction<float> OnMusicVolumeChanged;

    /// <summary>
    /// Unity method called on component enable.
    /// Used to attach listeners to sliders.
    /// </summary>
    private void OnEnable()
    {
        soundSlider.onValueChanged.AddListener(ChangeSoundVolume);
        musicSlider.onValueChanged.AddListener(ChangeMusicVolume);
    }

    /// <summary>
    /// Unity method called on component disable.
    /// Used to attach listeners to sliders.
    /// </summary>
    private void OnDisable()
    {
        soundSlider.onValueChanged.RemoveListener(ChangeSoundVolume);
        musicSlider.onValueChanged.RemoveListener(ChangeMusicVolume);
    }

    /// <summary>
    /// Invokes OnSoundVolumeChanged action with received parameter.
    /// </summary>
    /// <param name="value">Sound Volume Value. (0.0001 - 1)</param>
    public void ChangeSoundVolume(float value)
    {
        OnSoundVolumeChanged?.Invoke(value);
    }

    /// <summary>
    /// Invokes OnMusicVolumeChanged action with received parameter.
    /// </summary>
    /// <param name="value">Music Volume Value. (0.0001 - 1)</param>
    public void ChangeMusicVolume(float value)
    {
        OnMusicVolumeChanged?.Invoke(value);
    }
}

Cool! So the only thing left is to connect UIAudioSettings and AudioController together.

using UnityEngine;

/// <summary>
/// This class connects View and Controller.
/// </summary>
public class UsageExample : MonoBehaviour
{
    // Reference to audio controller.
    [SerializeField]
    private AudioController audioController;

    // Reference to ui audio settings view.
    [SerializeField]
    private UIAudioSettings audioSettings;

    /// <summary>
    /// Unity method called on component enable.
    /// Used here to attach actions.
    /// </summary>
    private void OnEnable()
    {
        audioSettings.OnSoundVolumeChanged += audioController.ChangeSoundVolume;
        audioSettings.OnMusicVolumeChanged += audioController.ChangeMusicVolume;
    }

    /// <summary>
    /// Unity method called on component disable.
    /// Used here to attach actions.
    /// </summary>
    private void OnDisable()
    {
        audioSettings.OnSoundVolumeChanged -= audioController.ChangeSoundVolume;
        audioSettings.OnMusicVolumeChanged -= audioController.ChangeMusicVolume;
    }
}

And now time to test it!

The result ?

Volume system in action!

It looks nice! But it’s even better with the music playing! Unfortunately, the gif can’t play music, so you have to believe me… ?

What do you think about it? Let me know in the comment section below!

If you want to get notified of future content, sign up for the newsletter!

As always, the whole project is available at my public repository. ?

And I hope to see you next time! ?

5 1 vote
Article Rating
Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Shavais
Shavais
2 years ago

I need the volume of a given sound any any moment to be affected by the global sound effects setting from a slider, and also by a value that depends on the particular sound, and also by that sound instances “fade state”…

1
0
Would love your thoughts, please comment.x
()
x