【Unity】AudioMixerで遊んでみよう!(2/3)
前回の続きです。
AudioMixer経由で音を再生することが出来ました。
今回の内容
・キャラボイスの再生やBGMクロスフェードを行うスクリプトを実装
・そのスクリプトを呼び出すUI(トグル)を実装
・AudioMixerのグループにエフェクトを追加してみる
・AudioMixerのスナップショット機能を利用してみる
ではさっそくスクリプトを追加していきましょう。
Assets直下へのファイル直置きは避けてScriptsフォルダを作ってその中にSample01Controllerを作成しましょう。
スクリプトはこちらをコピペして下さい。
Sample01Controllerという名前のゲームオブジェクトを作成してAddComponentでこのスクリプトを追加して下さい。
Inspectorで設定する部分がちょっと多いですが、めげずに設定していきましょう。
ClipとついているものはAudioClipを、それ以外はシーンのゲームオブジェクトを設定して下さい。
この画像の通りに設定が出来たら呼び出し側のUI(トグル)を実装します。
Hierarchyウィンドウで何も選択されていない状態で右クリック→UI→Toggleで作成します。
これでEventSystemとCanvasとToggleが一気に生成されると思います。
ゲームオブジェクト名をBattleToggleに変更し、サイズが小さい感じなのでscaleを2へ、そしてToggleコンポーネントのIsOnのチェックを外します。
BattleToggleを選択した状態でCtrl+Dを2回押し、FieldToggleとMenuToggleを作成します。
座標が同じで被っているのでずらします。
こちらではFieldToggleのPosYに-40、MenuToggleのPosYに-80を入力しました。
Gameビューを見るとToggleが3つ並んでいて意味不明なので、各Toggleの子供のLabelオブジェクトのTextを変更します。
BattleToggleはBattle、FieldToggleはField、MenuToggleはMenuと入力していきます。
UI作成はこれで終わりです。Gameビューが画像のような感じになっていればOKです。
※ToggleのIsOnをオフにした場合でも、一度実行するまではGameビューの表示状態には反映されません。なのでこの段階で既に一度実行されている方は全てのチェックが外れて見えると思います。
UIとして追加した部分のHierarchyビューはこんな感じになっているはずです。
次にSample01Controllerに先程作成したToggleたちを設定していきます。
画像のようにこの3箇所を設定して下さい。
そしてBattleToggleのOnValueChangedにSample01ControllerゲームオブジェクトのSample01.ChangedBattleToggle()を設定します。
※FieldToggleとMenuToggleは後から設定します。
ここで設定した関数は、チェックのオンオフが切り替わるたびに呼ばれます。
ここまで出来たら一旦実行してみましょう。
バトルのToggleにチェックを入れるとBGMがクロスフェードしつつエンカウントしたっぽい感じのSEと戦闘開始ボイスが流れます。
チェックを外すとリザルトっぽいSE(ジングル)とボイスが流れた後にフィールドのBGMに戻ります。
これだけでもゲーム画面のイメージが出来てしまうゲームサウンドパワーすごい!音楽素材をお借りした各サイト様ありがとうございました!!
個人的にはスターオーシャンとかテイルズみたいな雰囲気を思い出しました。
スクリプト処理内容は非常にシンプルです。実はまだAudioMixer固有のスクリプトではなく、単純にAudioSourceのボリュームでフェードイン、フェードアウトを実装しています。
下準備完了
結構長い下準備が整ったところでAudioMixerのエフェクトとスナップショット機能を使っていきます。ここからが本番と言っても過言ではないです。
エフェクトを使ってダッキングの実装、洞窟っぽい鳴り方の再現に挑戦していきます。
ダッキングは「ある音を再生中は一時的に別の音量を下げる」とざっくり説明しましたが、今回のケースに当てはめると
Voiceグループを再生中は、BGMとSEグループの音量を下げるという形での実装にしようと思います。
たしかに今の状態だと声が埋もれて聞きづらい感じがしますね。
BGMグループとSEグループにDuck Volumeエフェクトを追加していきます。
どちらもThresholdを-30.00dBに設定して下さい。
次にVoiceグループにSendエフェクトを2個追加します。
それぞれSendのReceiveにBGM Duck Volume、SE Duck Volumeを設定します。
どちらもSend levelを0dBに設定して下さい。
これで実行してみましょう。
声の再生時にBGMとSEの音量が下がって、だいぶ声が聞こえやすくなったと思います。
今回はサンプルなので効果がはっきりわかるようにガッツリかけていますが本来はもう少し軽い方が良さげです。
では次に洞窟っぽい鳴り方を再現してみましょう。
リバーブというエフェクトを使います。
SEグループとVoiceグループにSFX Reverbエフェクトを追加していきます。
どちらもRoomを0.00mBに設定して下さい。
これで実行してみましょう。
水音と声にエフェクトが掛かって洞窟っぽい感じになったと思います。
エフェクトはこれで完成としましょう。
エフェクトに関しての理解度を上げたい場合はUnityのエフェクトとしてではなく一般的な音楽制作の知識として調べた方がより理解しやすく纏められていると思います。
やっとスナップショット!
最後にスナップショットを使ってみましょう。
スナップショットは名前の通りの機能で、対象AudioMixerのエフェクトの状態を保存しておく事が出来ます。
例えば先程作成した洞窟リバーブ状態と草原のリバーブなし状態を保存しておいて、フィールド切り替えにあわせて変更したり出来ます。
では、今の状態は洞窟リバーブが掛かっている状態だと思いますのでAudioMixerウィンドウのSnapshotsからSnapshotを右クリックしてCaveにリネームしましょう。
これで洞窟用のスナップショットが出来ましたので、次に草原用のスナップショットを作っていきます。
Snapshots+をクリックすると現在のスナップショットが複製されますので名前をGrasslandにします。
そしてGrasslandを右クリックしてSet as start Snapshotをクリックして下さい。
これで実行時にGrasslandから始まるように設定されます。スナップショット名の横にある☆マークがそれを示しています。
まだこのままだと草原フィールドなのにリバーブが掛かった状態ですので掛からないようにします。
Grasslandをクリックして選択された状態して下さい。こうする事でGrasslandのスナップショットが編集されます。
そしてSEグループとVoiceグループのSFX ReverbエフェクトのRoomを-10000.00mBに設定します。
ここで注意して欲しいのが、リバーブを掛けたくないからと言ってSFX Reverbごと削除してはいけません。
もし削除してしまった場合は、洞窟側のSFX Reverbも消えてしまいます。
Snapshotごとにエフェクトを付けたり外したりは出来ずパラメータの調整でエフェクト有無を表現する必要があります。
正直使いづらい…。
ここで一旦実行して確認してみましょう。
リバーブが掛かっていない状態で実行されていると思います。
続いてメニュー用のスナップショットも作成してしまいましょう。
今回作成するメニュー画面風サウンドは「BGMとSEの音量が下がった状態でそのまま再生され続ける」にしてみます。
バトル中にメニューを開けばバトルのBGMとSEが小さく聞こえて、フィールド画面で開けばフィールドのBGMとSEが小さく聞こえるようにします。
AudioMixerウィンドウのSnapshotsからGrasslandを右クリックして、Duplicateをクリックして複製しましょう。
名前はMenuにします。Menuをクリックして編集するスナップショットに設定しておきます。
続いてBGMグループとSEグループのAttenuationエフェクトのVolumeに -10.00dB を設定します。
これで、Menuのスナップショット使用時にはBGMとSEのボリュームが下がるようになります。
長くなりましたが、スナップショット側の設定はこれで終わりです。
あとはInspector側の設定で完成まで持っていきます。
Sample01Controllerにスナップショットたちを設定します。
これはスナップショットの変更スクリプトのために設定しています。
変更スクリプトはとても単純でToggleのオンオフを見て適切なスナップショットのこの関数を使用しているだけです。
AudioMixerSnapshot.TransitionTo(float timeToReach);
Audio.AudioMixerSnapshot.TransitionTo - Unity スクリプトリファレンス
最後にUIから操作
最後にToggleから操作出来るようにしましょう。
FieldToggleのOnValueChangedにSample01ControllerゲームオブジェクトのSample01.ChangedFieldToggle()を設定します。
同様にMenuToggleのOnValueChangedにSample01ControllerゲームオブジェクトのSample01.ChangedMenuToggle()を設定します。
さあここまで出来たら実行してみましょう!
FieldToggleで洞窟リバーブのオンオフが出来て、MenuToggleでいつでもメニューっぽい感じになると思います!
※余談になりますがMenuToggleがオンになる時とオフになる時に音が少し変わっていますが、これは1つのファイルの順再生と逆再生で実現しています。条件付きではありますが、非常にシンプルなスクリプトで実装出来るので興味のある方はこちらの記事をどうぞ。
完成?
一見すると最初の記事の完成系まで持っていけたように思いますが、実はまだ出来ていない部分があります。
よく聞かないとわからないかもしれませんが、リバーブがオンの状態でメニューを開いたときに、リバーブがオフになっています。
これはMenuスナップショットを作成する際にGrasslandを複製したのでリバーブがオフになっています。
今回のケースのみを考えるなら洞窟用のMenuスナップショットを作成すれば解決出来ます。
ですが洞窟以外のフィールドが出て来るたびに、Menuスナップショットが増えていくのはイマイチな感じがします…。
というわけで、次回の最終回はこれに対する解決策をご紹介します!