この記事はUnity Advent Calendar 2019の12日目の記事です。
この記事でのバージョン
Unity 2017.4.17f1
Unity 2018.4.13f1
Unity 2019.2.15f1
はじめに
以前、AudioManagerの記事を公開したのですが、
Unityは音を鳴らすのがちょっと面倒なせいか、いまだに結構多くの方に使ってもらえているらしいです。
公開から年数も経ってますし、いつかプログラムも記事も書き直したいな〜と思っていたのですが、
どう考えても時間がめっちゃかかるので後回しにしてたら、5年も経ってしまっていました。
という事で今回は、Advent Calendarに乗じてAudioManagerを一新しようという感じの記事です!
なお、「初心者の方でも簡単に使える」というのを目標に作っています。
AudioManagerとは
そもそもAudioManagerとはなんぞやという話からですが、
読んで字の如く、BGMやSEなどのオーディオファイルの再生や停止を管理する物です。
Unityは音を鳴らすだけでもAudioSouce、AudioListener、AudioClipなど様々な要素が関わってくるので、
色々準備や設定が面倒ですし、初心者が混乱するポイントだったりもします。
そこで、とにかく簡単に音を鳴らすためにAudioManagerを作りました!
導入
今回のAudioManagerはGitHubに公開してみました。もちろん完全無料で使えます!
GitHubがよう分からんという方は、Download ZIPからzipファイルをダウンロードするだけでOK。
後はUnityPackageを自分のプロジェクトへインポートするだけ。
ちなみにインポートされたAudioManager_KanKikuchiという
ディレクトリは移動しても名前を変えてもOKです。
使い方
AudioManagerを導入すると、
どのシーンを再生してもBGMManagerとSEManagerのオブジェクトが自動生成されるようになり、
いつでもどこでもBGMやSEを簡単に再生出来るようになります。
例えばプログラムからSEを再生したい場合は1行追加するだけです。
//System20というSEを再生
SEManager.Instance.Play(SEPath.SYSTEM20);
ただし、シーン上にAudioListenerが最低1つは必要です。
(デフォルトのカメラに付いているので、特に設定は不要なはずです。)
なお、基本的な動作はBasicSampleSceneを見ると分かりやすいかと思います。
オーディオファイル(AudioClip)の場所
オーディオファイル(AudioClip)はAudioManager_KanKikuchi/Resourcesの下に配置します。
なお、BGMとSEはディレクトリを分けてありますが、
BattleやJingleのようにそれより下にディレクトリを追加する事は可能です。
また、デフォルトで配置されているファイルを削除したり、新たに追加する事も、もちろん可能です。
ただし、サンプルでエラーが出るので、その場合はサンプルをディレクトリごと消してください。
オーディオファイルを追加したり名前を変えたりすると、
パスを管理するクラス(BGMPathとSEPath)が自動で更新され、
ディレクトリごとにAudioClipの設定も自動で更新されます。
プログラム
ここでは実際にプログラムでどう使うかの紹介です。
なお、AudioManager関連の機能を使うにはusing KanKikuchi.AudioManager;の記述が必要になります。
再生
BGMの再生にはBGMManagerを使います。
以下のようにInstanceにアクセスして使う感じなので、どこからでも再生可能です!
BGMManager.Instance.Play(BGMPath.BATTLE27);
なお、再生時に色々と設定する事も可能です。(audioPath以外は全て省略可能)
BGMManager.Instance.Play( audioPath : BGMPath.BATTLE27, //再生したいオーディオのパス volumeRate : 1, //音量の倍率 delay : 0, //再生されるまでの遅延時間 pitch : 1, //ピッチ isLoop : true, //ループ再生するか allowsDuplicate : false //他のBGMと重複して再生させるか );
SEの再生にはSEManagerをBGMと同じような感じで使います。
SEManager.Instance.Play(SEPath.SYSTEM20);
ただし、BGMとは違い引数でcallbackが指定出来ます。(SEの重複再生は常に可能)
SEManager.Instance.Play( audioPath : SEPath.SYSTEM20, //再生したいオーディオのパス volumeRate : 1, //音量の倍率 delay : 0, //再生されるまでの遅延時間 pitch : 1, //ピッチ isLoop : true, //ループ再生するか callback : null //再生終了後の処理 );
ちなみに、前述の通りBGMPathやSEPathは自動更新されるので、
使いたいオーディオファイルを入れるだけで、プログラムからもすぐに使えます。
ボリュームの変更
音源ごとのボリュームはPlayのvolumeRateで指定しますが、
全体のボリュームを変更したい時にはChangeBaseVolumeを使います。
/*volumeはfloat*/ //BGM全体のボリュームを変更 BGMManager.Instance.ChangeBaseVolume(volume); //SE全体のボリュームを変更 SEManager.Instance.ChangeBaseVolume(volume);
なお、再生中の音のボリュームも変更されます。
停止
再生しているものを停止させたい時はStopを使います。
//全てのBGMを停止 BGMManager.Instance.Stop(); //全てのSEを停止 SEManager.Instance.Stop();
なお、指定した音源だけを停止する事も可能です。
//BATTLE27のBGMだけを停止 BGMManager.Instance.Stop(BGMPath.BATTLE27); //SYSTEM20のSEだけを停止 SEManager.Instance.Stop(SEPath.SYSTEM20);
一時停止と再開
一時停止させたい時はPause、再開させたい場合はUnPauseを使います。
//全てのBGMを一時停止 BGMManager.Instance.Pause(); //全てのSEを一時停止 SEManager.Instance.Pause();
//一時停止している全てのBGMを再開 BGMManager.Instance.UnPause(); //一時停止している全てのSEを再開 SEManager.Instance.UnPause();
なお、指定した音源だけを一時停止及び再開する事も可能です。
//BATTLE27のBGMだけを一時停止 BGMManager.Instance.Pause(BGMPath.BATTLE27); //SYSTEM20のSEだけを一時停止 SEManager.Instance.Pause(SEPath.SYSTEM20);
//一時停止しているBATTLE27のBGMだけを再開 BGMManager.Instance.UnPause(BGMPath.BATTLE27); //一時停止しているSYSTEM20のSEだけを再開 SEManager.Instance.UnPause(SEPath.SYSTEM20);
フェードイン、フェードアウト
フェードインさせたい時はFadeIn、フェードアウトさせたい場合はFadeOutを使います。
また、Fadeを使えばで指定の範囲でフェードさせる事も可能です。
//全てのBGMをフェードアウト BGMManager.Instance.FadeOut(); //全てのSEをフェードイン SEManager.Instance.FadeIn();
もちろん、引数でフェードする時間やフェード後の処理を指定する事も出来ますですし、
指定した音源だけをフェードする事も可能です。
//再生しているBATTLE27だけ2秒でーフェードアウトし、フェードアウト後にログを表示 BGMManager.Instance.FadeOut(BGMPath.BATTLE27, 2, () => { Debug.Log("BGMフェードアウト終了"); });
再生中のものを取得
IsPlayingで現在再生しているか、
GetCurrentAudioNamesで現在再生しているオーディオ名を取得する事が出来ます。
if (BGMManager.Instance.IsPlaying()) { /*BGMが再生している時の処理*/ }
//再生中のSEの名前を全て取得
var currentSENames = SEManager.Instance.GetCurrentAudioNames();
Manager以外の便利なクラス
Manager以外にも、便利なクラスをいくつか用意したので、それについても紹介しておきます。
SEAssistant
SEAssistantをSEをさらに簡単に再生するためのクラスです。
オブジェクトにAddし、鳴らしたいAudioClipを設定した後、
ボタンなどに登録すると、プログラム無しでSEを再生できます。
(もちろんSEAssistantをプログラムから使う事も可能)
なお、Inspectorの各設定項目の内容は以下の通りです。
- Audio Clip : 再生する対象
- Is Auto Play : 自動で再生を開始するか
- VolumeRate : ボリュームの倍率
- Delay : 再生開始前の遅延時間
- Pitch : 再生時のピッチ
- Fade In Duration 再生開始時のフェードイン時間(0ならフェードインしない)
- Is Loop : ループ再生するか
ちなみにAssistantSampleのボタンで使用例を確認出来ます。
(ただし、AssistantSample1とAssistantSample2をビルドターゲットに設定する必要が有り)
BGMAssistant
BGMAssistantをBGMをさらに簡単に再生するためのクラスです。
SEAssistant同様にプログラム無しでBGMを再生でき、
シーンごとに自動でBGMを変更するなんて事も可能です。
(もちろんBGMAssistantをプログラムから使う事も可能)
なお、Inspectorの各設定項目の内容は以下の通りです。
- Audio Clip : 再生する対象
- Is Auto Play : 自動で再生を開始するか
- VolumeRate : ボリュームの倍率
- Delay : 再生開始前の遅延時間
- Pitch : 再生時のピッチ
- Fade In Duration 再生開始時のフェードイン時間(0ならフェードインしない)
- Fade Out Duration 再生終了時のフェードアウト時間(0ならフェードアウトしない)
- Is Loop : ループ再生するか
- Is Auto Stop : シーン遷移時に自動で停止するか
これもAssistantSampleで使用例を確認できます。
BGMSwitcher
BGMSwitcherはBGMの切り替えを簡単に行うためのクラスで、
以下のように現在再生中のBGMを1行で好きなように切り替えられます。
(PlayやFade等と同様に省略可能な引数が多数あります)
//再生中のものをフェードアウトさせて、BATTLE27を再生開始する BGMSwitcher.FadeOut(BGMPath.BATTLE27); //再生中のものを即停止させて、BATTLE27をフェードインで開始する BGMSwitcher.FadeIn(BGMPath.BATTLE27); //再生中のものをフェードアウトさせて、BATTLE27をフェードインで開始する BGMSwitcher.FadeOutAndFadeIn(BGMPath.BATTLE27); //再生中のものをフェードアウトさせて、同時にBATTLE27をフェードインで開始する BGMSwitcher.CrossFade(BGMPath.BATTLE27);
なお、実際の動作はBGMSwitchSampleで確認できます。
機能と設定
パスの自動更新など、特殊な機能がいくつか登場しましたが、最後にその機能をまとめておきます。
またそれらの設定はResourcesの下にあるAudioManagerSettingの
Inspectorから変更する事が出来ます。(基本的にはデフォルト設定で問題はないはず)
Resourcesへのパスの自動更新
ResourcesへのパスをまとめたクラスであるBGMPathとSEPathは自動で更新されます。
ただし、対象はAudioManager_KanKikuchi/Resources/BGMやSE以下のAudioClipだけです。
(AudioManager_KanKikuchiのディレクトリ名は変更可能)
なお、設定から自動更新をなくす事も可能です。
また、上部メニューから手動で更新する事も可能です。
同時再生(可能数)
BGMもSEも同時に複数のものを再生する事が可能ですが、その再生可能数を設定出来ます。
なお、再生可能数を超えた場合、一番古い音源の再生が強制的にストップします。
ボリューム設定
各音源ではなく全体のボリュームを設定する事も出来ます。
SEのボリューム倍率調整
同時に同じSEを流すと爆発的にボリュームが上がり、音割れを引き起こす事がありますが、
それが起こらないように自動で調整するように実装してあります。
ただし、その調整が必要ない場合は設定から無くすことも出来ます。
Managerの自動生成と破棄
Managerはシーン再生時に自動で生成され、永久に破棄されませんが、
設定から自動で生成しない事も可能ですし、
シーンを跨ぐ時に破棄する設定にする事も可能です。
なお、同然ですがManagerがないと機能は使えないので、
自動生成しない場合は以下のような感じで手動で生成する必要があります。
//AudioManagerの生成
gameObject.AddComponent<BGMManager>();
gameObject.AddComponent<SEManager>();
キャッシュ
AudioClipは何度もロードしないようにキャッシュしていますが、その設定も変える事が出来ます。
オーディオファイルの設定の自動更新
AudioManager_KanKikuchi/Resources/BGMやSE以下の
AudioClipの設定は自動で行うようになっていますが、その自動の設定をなくしたり、
自動の設定の内容を変える事も出来ます。
また設定ファイルのボタンやメニューから手動で設定を更新する事も可能です。
おわりに
5年ぶりに1から作り直しましたが、予想通りめちゃめちゃ時間かかりました……!
そのおかげで手前味噌ながら、結構良いものが出来た気がしますのでドンドン使ってみてください!
ただし実際に運用したわけでないので、バグ等があるかもしれないという事だけご注意ください。
なお、その際は報告を頂けると幸いです。(すぐに直せるとは限りませんが……)