背景
一週間でゲームを作るイベント「Unity1Week」では沢山のゲームを次々に遊ぶため、ゲームに音量調整機能が付いていることが望ましいという風潮があります。
一応AudioListener.volume
で音量調整を実現できますが、BGMとSEを区別できません。
私はBGMとSEを区別したかったので、AudioMixerでそれぞれの音量を調整できるスライダーを作りました。
アピールポイント
10段階調整も可能です(Slider の Whole Numbers を有効にして Max Value を 10 にする)。
本コンポーネントの Optoion Check XXX に AudioClip と AudioMixerGroup をアタッチすると、音量変更時に音を鳴らせます。これで音量が適切かすぐに確認できます。
前提
各 AudioSource の Output に AudioMixerGroup を指定する必要があります。
AudioMixer のパラメータを出して、スクリプトから変更可能にする必要があります。
留意点
音量情報の保存方法は PlayerPrefs です。
パラメータの指定方法はハードコードです。
コード
AudioMixerVolumeSlider.cs
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.UI;
namespace GameJam
{
[RequireComponent(typeof(Slider))]
public class AudioMixerVolumeSlider : MonoBehaviour
{
[SerializeField] private AudioMixer mixer;
[SerializeField] private string audioMixerParameterName = "BGMVolume";
[SerializeField] private AudioClip optionCheckClip;
[SerializeField] private AudioMixerGroup optionCheckMixerGroup;
private AudioSource audioSource;
private void Start()
{
var slider = GetComponent<Slider>();
var volume = PlayerPrefs.GetFloat(audioMixerParameterName, GetNormalizedValue(slider));
slider.enabled = false;
slider.value = volume == 0f ? 0f : volume * slider.maxValue;
slider.enabled = true;
slider.onValueChanged.AddListener(_ => OnValueChanged(slider));
SetVolume(volume);
}
private void OnValueChanged(Slider slider)
{
SetVolume(GetNormalizedValue(slider));
PlayerPrefs.SetFloat(audioMixerParameterName, GetNormalizedValue(slider));
PlayerPrefs.Save();
if (optionCheckClip == null) return;
if (audioSource == null)
{
audioSource = gameObject.gameObject.AddComponent<AudioSource>();
audioSource.playOnAwake = false;
audioSource.clip = optionCheckClip;
audioSource.outputAudioMixerGroup = optionCheckMixerGroup;
}
audioSource.Play();
}
private float GetNormalizedValue(Slider slider) => slider.value == 0f ? 0f : slider.value / slider.maxValue;
private void SetVolume(float volume) => mixer.SetFloat(audioMixerParameterName, VolumeToDecibel(volume));
private float VolumeToDecibel(float volume) => Mathf.Clamp(20f * Mathf.Log10(Mathf.Clamp(volume, 0f, 1f)), -80f, 0f);
}
}