概要
ゲームをプレイしているとよく見るオプションからBGMやSEの音量を変更する機能。これを実現するのに、Audio Mixer の Group 機能を使った方法をよくネットで見かける。Edior ではなんら問題なく動作するが、Android や iOS でビルドすると音量変更が全然動作しない。この記事はこの問題に対する対策を記録するためのもの。
結論
Audio Source の存在する Prefab 全てに、Audio Mixer Binder という自作のコンポーネントを追加することで解決。Audio Mixer Binder の振る舞いとしては、当該 Prefab がインスタンス化された際に、SoundManager と結合している Audio Mixer から、各種 Audio Mixer Group を取り出し、Audio Source の outputAudioMixerGroup を上書きして参照解決するというもの。
public class AudioMixerBinder : MonoBehaviour
{
private AudioSource audioSource;
void Start()
{
audioSource = GetComponent<AudioSource>();
// audioSource に設定されているものと同じミキサーグループをサウンド管理から得る
var groups = Manager.Sound.GetMixer().FindMatchingGroups(audioSource.outputAudioMixerGroup.name);
// 指定したミキサーグループがあるか?
if (groups.Length == 0)
{
Print.Game.Error("[Audio] Not found audio mixer group. name=" + audioSource.outputAudioMixerGroup.name);
return;
}
// ミキサーグループを設定する
audioSource.outputAudioMixerGroup = groups[0];
}
}
見てわかる通り、AudioSource にあらかじめ設定されている AudioMixerGroup と同じ名前の AudioMixerGroup をSoundManagerから取り出して上書きしている。こうすることで、SoundManager の管理する AudioMixerGroup のたとえば、BGM などの音量を変更すると、ちゃんと当該 AudioSource の音量も変更されるようになった。
参考にした記事
https://discussions.unity.com/t/audiomixer-sub-groups-volume-on-android/898472/2
この記事によると、Addressable のビルドを行うことで、Audio Mixer が各 Audio Source ごとのパッケージにハードコピーされるとのこと。つまり、SoundManager 側にアタッチしている Audio Mixer をいくら操作しても、全然別のメモリに存在する Audio Mixer を使って動いている Audio Source のボリュームは変更することができないということになる。参考記事のコメントにもある通り、挙動や理由は理解することができるが、直感的ではないし、Editor では問題なく動作するので本件はUnity側にどうにか対応してほしいと思う。
環境
Unity 2022.3.39f1