Unity5ではAudioMixerというAPIがある
俺はオレオレ仕様が大嫌いだ。いい設計とは無駄なマイノリティを発揮しないことだと思う。
ただUnity4.xまではAudioSourceから発された音源はそのままAudioListenerに届くため、ゲーム内のコンフィグ画面などでBGM,SEなどを調節するスライダーを設置する際に、大抵は自作のAudioManagerなるものを作り(空オブジェクトにC#貼り付けたようなアレ)、そこにBGMに使う系のAudioSource、SEに使う系のAudioSourceをインスペクターから登録できるような仕様のものを作ることになると思う。
ただUnity5ではAudioMixerがあるのでオレオレAudioManagerをやめてこの公式APIを活用した方がスマートだと思う。
今回は音量を調節することを例にして解説するが、歪み(ひずみ)などその他のパラメータの調節もこの方法で可能だ。
AudioMixerを使う
まだ使ったことがない人は空っぽになっていると思うので左にあるGroupsの+をクリックしていくつかのGroupを作成する。とりあえずBGMとかSEとかがあればいいと思う。
図のように入れ子にすることができる。SE配下にVoice,Weapon,Playerを作成している。
作成したGroupのうち一つを選択した状態でInspectorは下のように表示される。
Exposeを選ぶことで任意のパラメーターをスクリプトから操作できるようになる。
今回はVolumeをExposeする。
Exposeしたパラメーターは下の図のように右上の小さなプルダウンから確認できる。ここでパラメーターに名前を付け直すことが出来るのでここでは全てなんたらVolumeという名前をつけておいた。
一旦ここでAudioSourceから出た音をAudioMixerに通す方法を解説する。
これは簡単である。
まずはAudioSourceコンポーネントをもつゲームオブジェクトを選択しInspectorにAudioSourceコンポーネントを表示させる。
あとは図のようにOutput Audio Mixer Groupに先ほど作成したGroupのうちの一つを選んで登録する。
これでこのAudioSourceからの音はAudioMixerで音量、エフェクトともに操作できるようになった。
あとはAudioMixerクラスのSetFloatメソッドで値を操作できる。
http://docs.unity3d.com/ScriptReference/Audio.AudioMixer.SetFloat.html
audioMixer.SetFloat("パラメーター名", float値);
という感じで使えばいい。
例えばUnityのGUIのSliderで操作する仕様にしたければ
というふうにMinとMaxと設定すればSliderの値をそのまま音量に使える。最大値を0以上にすると音割れすることがあるので上限は0が良い。
PlayMakerを使ってノースクリプトで作りたい人のためにヒントを載せておく。
uGuiのSliderの値のGetやSetはEcoSystemで入手すると良い。
AudioMixerに関するPlayMakerのアクションは現状ではEcoSystem上で検索しても一つも出てこなかったので今からプレゼントする。
using UnityEngine;
using HutongGames.PlayMaker;
using UnityEngine.Audio;
namespace HutongGames.PlayMaker.Actions {
[ActionCategory(ActionCategory.Audio)]
[Tooltip("Sets the value of the exposed parameter specified.")]
public class AudioMixerSetFloat : FsmStateAction {
[ObjectTypeAttribute(typeof(AudioMixer))]
[Tooltip("Target AudioMixer.")]
public FsmObject audioMixser;
[Tooltip("Value to set.")]
public FsmFloat value;
[Tooltip("Exposed Parameter's name.")]
public FsmString name;
// Code that runs on entering the state.
public override void OnEnter() {
var mixer = audioMixser.Value as AudioMixer;
mixer.SetFloat(name.Value, value.Value);
Finish();
}
}
}
それではチャオ!