Let me just say “DEAR LORD, NO” at the prospect of changing the volume of individual AudioSources with an option slider, like others here have suggested.
What you should be using for Volume control is an AudioMixer, through which you can even set up multiple MixerGroups to control different parts of the audio (like Music and SFX).
To do this you’ll first need to create an AudioMixer asset in your project. You can then double-click it to open it in the AudioMixer window. In that window you can add more mixer groups. Select the mixer group you want to control the volume of, right-click the Volume parameter in the Inspector and click “Expose to script”. You can then change the name of this exposed parameter to something convenient in the AudioMixer window; “MasterVol” is a good start. Now that the parameter is exposed you can change it in a script with the SetFloat function. Ensure that each of your audio sources are using the Mixer you wish to control them through.
Finally, here’s a script for interfacing between the Slider and the exposed Volume parameter:
using UnityEngine;
public class VolumeSlider : MonoBehaviour {
public UnityEngine.UI.Slider slider;
public UnityEngine.Audio.AudioMixer mixer;
public string parameterName;
void Awake(){
float savedVol = PlayerPrefs.GetFloat(parameterName, slider.maxValue);
SetVolume(savedVol); //Manually set value & volume before subscribing to ensure it is set even if slider.value happens to start at the same value as is saved
slider.value = savedVol;
slider.onValueChanged.AddListener((float _) => SetVolume(_)); //UI classes use unity events, requiring delegates (delegate(float _) { SetVolume(_); }) or lambda expressions ((float _) => SetVolume(_))
}
void SetVolume(float _value){
mixer.SetFloat(parameterName, ConvertToDecibel(_value/slider.maxValue)); //Dividing by max allows arbitrary positive slider maxValue
PlayerPrefs.SetFloat(parameterName, _value);
}
/// <summary>
/// Converts a percentage fraction to decibels,
/// with a lower clamp of 0.0001 for a minimum of -80dB, same as Unity's Mixers.
/// </summary>
public float ConvertToDecibel(float _value){
return Mathf.Log10(Mathf.Max(_value, 0.0001f))*20f;
}
}
NOTE: slider MaxValue needs to be above 0 and values below 0 are ignored, so MinValue should be 0
Reference your Slider in the “slider” field, reference the mixer you wish to control in the “mixer” field and enter the name of the exposed Volume parameter you wish to change in the “parameterName” field (e.g. “MasterVol”).
That’s it. You can also put that script on other sliders with different “parameterName” values to control other MixerGroup volumes (e.g. “Music” and “SFX”).
The script also saves and loads your setting from/to PlayerPrefs, using the name of your exposed parameter, so it doesn’t change between scenes or sessions.
Bonus: There’s a Unity tutorial on how to expose AudioMixer parameters, if you got lost somewhere in my text, just don’t use the same slider min and max values as they do, they don’t do the logarithmic conversion I do in my script. There are other useful tutorials in the (Learn game development w/ Unity | Courses & tutorials in game design, VR, AR, & Real-time 3D | Unity Learn)-section as well if you’re new to the topic.