退廃的ソースコードコンテナ

ゲームシステムを組むのが好きな人の備忘録

【Unity】インスペクターから登録したニックネームで再生できるサウンドマネージャーを作ってみた

 

サウンドマネージャーの役割

Unityに限らず、ゲームを作る上では必須のサウンド

多くのゲームの場合、「サウンドマネージャー」と呼ばれるクラスはサウンドの管理と再生の、両方の役割を担っていることが多いです。

 

Unityでサウンドを再生する場合、AudioClipと呼ばれる音楽データと、AudioSourceという音楽を再生するコンポーネントが必要になってきます。また、AudioListenerと呼ばれる音楽を聞くコンポーネントも存在しますが、基本的にカメラなどに付属しておりサウンドマネージャーの管轄外のため、今回は説明を省きます。

 

さて、このサウンドマネージャーはAudioClipを登録して、呼び出されたらAudioSourceに音楽を登録して再生するといった役割を担っています。また、mp3やwavなどの音楽データはボリュームがバラバラであることもあるので、そのボリュームを個別に登録して音量を調整する役割も必要です。

 

今回紹介するサウンドマネージャーはインスペクターからAudioClipを登録できる他、インスペクターからニックネームを登録できて、その関数を呼ぶとニックネームだけで音楽を再生できるというものです。

 

呼び出すときも再生するときも一行だけ。便利なので、是非お使いください。

ソースコード

長過ぎるので最後に貼ります。申し訳ない…。

ソースコードはこちら

 

使い方と関数説明

前提条件

このSoundManagerを使用する上では、以前の記事で紹介したシングルトン設計のクラスを継承します。

 

オリジナルのシングルトン設計のMonoBehaviourが存在する場合はそちらを継承元に変えていただいて構いませんが、基本的にはこちらのソースコードを使用することを推奨します。

 

こちらのSingletonMonoBehaviourはアタッチする必要がなく、Unityのプロジェクト上に存在するだけで構いません。また、シングルトン設計が分からないという方は以下の記事に説明が書いてありますので、そちらをお読みください。

islingtonsystem.hatenablog.jp

 

再生方法・停止方法

BGMとSEで再生する関数、停止する関数が分かれていますが、基本的に

ニックネームからSEを再生

ファイル名からSEを再生

以上の画像のような形で音楽を再生することができます。

インスペクターから登録したニックネーム、AudioClipの名前、どちらからでも音楽を再生することができます。

 

また、停止する際は以下の関数を使って止めることができます。

ニックネームからSEを停止

ファイル名からSEを再生

BGM・SEともに以下の関数を使うと音楽を全て再生停止することができます。

全てのSEを再生停止

全てのBGMを再生停止

 

インスペクターの説明

インスペクター
  • Volume
    全体のボリュームを制御する項目です。
  • BGM_Total_Volume
    BGMの全体のボリュームを制御する項目です。
  • SE_Total_Volume
    SEの全体のボリュームを制御する項目です。
  • BGM_PlaybackNum
    BGMの同時再生可能数を指定します。
  • SE_PlaybackNum
    SEの同時再生可能を指定します。

 

オーディオの登録方法

None(なし)となっているClipにAudioClipをドラッグアンドドロップ
  1. BGMDataかSEDataのプラス(+)ボタンを押して、配列を一つ追加する
  2. プロジェクト内にあるAudioClip(音楽データ)をClipにドラッグアンドドロップ
  3. 名前Sound Volume(音楽ファイルごとの個別音声)を任意で設定

 

この3ステップだけで、サウンドマネージャーに音楽を追加できます。

あとは、先程紹介したPlay関数で呼び出して再生するだけです。

 

名前の登録と音量について

音楽データのニックネームはインスペクターから登録できますが、何も登録されていない場合はファイル名からの呼び出しのみとなります。また、ニックネームとファイル名は必ずしもセットでなくてはいけないわけではないため、ニックネームはそのままで音楽データだけ差し替えることも可能です。

 

例えば、「このビーム音、なんだか微妙なんだよなぁ」のように思った時、ニックネームを登録しておけばプログラム側を改変すること無く、インスペクターから音楽データを差し替えてSEを変更することができます。地味に役立つと思うので、是非ご活用ください。

 

音楽データごとの個別音量については、『全体のボリューム×BGMまたはSEのボリューム×音楽データの個別音量』という計算式で割り出されています。BGMまたはSEのボリュームを変えた場合でも、音量が最上限に達しない限りはボリュームが反映されます。また、音量の調整は例に漏れず0~1の範囲内で調整をお願いします

 

音量調整

BGM音量調整のプロパティに値を代入

BGMとSEの音量調整はプロパティ(変数のように扱える関数)として用意されており、それの値を変更することで音量を調整できます。ゲームのオプション画面などでお使いください。

 

また、BGMとSEの音量調整だけでは物足りない、という方はインスペクターから変更できる全体のボリュームを変更してください。こちらはプログラムの中からは変更できる設定は用意されていないものの、全体のボリュームを上下したい場合はこちらが最適です。

 

音楽データごとの音量を調整する場合は、インスペクターからBGMDataもしくはSEDataの配列にあるSound Volumeを調整してください。「特定の音楽データの音量だけおかしい」のような場合は、こちらを調整するのが最適です。

 

なお、いずれも音量の値は0~1の範囲内で設定されているのでご注意ください。

 

詳しい情報

立体音響について

参照渡しでAudioSourceの値を書き換える

Unityの音楽再生の機能として、オブジェクトに近づくと音量が大きくなるSEを再生するオブジェクトがいる方向から音楽が聞こえる、といった立体音響機能が存在します。

 

立体音響機能を使う手順としては、まず足音やビーム音などを鳴らしたいオブジェクトにAudioSourceをアタッチして、そこで立体音響の聞こえ具合やどちらから聞こえるのかを調整します。

 

しかし、デフォルトのサウンドマネージャーの再生方法では、立体音響に対応していません。なぜなら、音楽を再生するAudioSourceがサウンドマネージャーに集約されているからです。

 

しかし、呼び出し元にアタッチしたAudioSourceを引数で渡すことで、サウンドマネージャーを立体音響に対応させることができます。AudioClipと音量設定はサウンドマネージャーで設定したものを、引き続き使用することができます。

 

この際、通常の引数での渡し方(引用渡し)では元の変数の値を書き換えることができないため、参照渡しと呼ばれる特別な引数の渡し方を行います。参照渡しの使い方は難しいことはなく、引数を入れる前にref修飾子を入れるだけです。入れ忘れた場合、コンパイルで構文エラーが出るかと思いますが、立体音響の機能を発揮できないのでご注意ください。

 

なお、上記の立体音響機能を使った場合、AudioSourceサウンドマネージャーの管理下を離れてオブジェクトが個別に保有する形となりますので、StopSEのような停止系関数は使えなくなります。AudioSourceを保有するオブジェクトの方で、個別に対応してください。

 

オーバーロードについて

PlaySEのオーバーロード一覧

C#には関数のオーバーロードという機能が用意されており、引数が違う同じ名前の関数を複数用意することができます。このサウンドマネージャーでもいくつかの関数で活用されており、引数の数と種類を変更することで違う処理を行うことができます

 

例えば、上記で説明したAudioSourceの引数渡しもオーバーロードの一つ。string型の文字列でタイトルを指定するだけでも使えますが、AudioSourceを引数で渡すと違う処理を行うことができます。

 

今回、PlayBGMPlaySEオーバーロードは使われており、主に3種類の処理が存在します。

  • 曲名を指定して再生
  • 曲名を指定して、引数で受け渡されたAudioSourceに情報を書き込む
  • 格納されている配列の番号を直接指定して再生

上記2つは既に説明済みなので省きますが、一番下の配列の番号を直接は文字列ではなくint型の配列番号でAudioClip(音楽データ)を指定するという方式です。

 

文字列から音楽データを検索する手間が減るので処理自体は軽くなりますが、インスペクターから配列番号を変えた場合に対応できず、違う音楽が再生されてしまう場合があるので、基本的には非推奨です。

 

音楽を再生する場合は、ニックネームもしくはファイル名から検索する方式をお使いください。

 

省略可能な引数について

引数には既に値が設定されている

先に紹介したオーバーロードと似たような機能になりますが、Unityで採用されているC#には省略可能な引数という機能が存在します。

 

省略可能な引数とは引数の値が初期状態で設定されており、呼び出し時に値を書き換えない限りはその値が採用されるというものです。つまり、特別なことを意識せず使えるが、いざという時には書き換えられるという便利な代物です。

 

今回、その省略可能な引数が採用されているのはPlayBGMとPlaySEの2種類です。

この両方は引数が少しだけ違うため、個別に紹介していきます。

 

PlayBGM

  1. string型:ニックネームもしくはファイル名(省略不可能)
  2. bool型:ループ再生の有無(省略不可能)
  3. float型:再生時のボリューム(省略可能

 

PlaySE

  1. string型:ニックネームもしくはファイル名(省略不可能)
  2. bool型:ループ再生の有無(省略可能
  3. float型:再生時のボリューム(省略可能
  4. bool型:同じ曲が再生中の場合は再生しない(省略可能

 

以上なのですが、再生時のボリュームに関しては値に-1がデフォルト設定されています。

-1を設定した場合、ボリュームに関する設定が無視される形となり、既に設定されているボリュームがそのまま反映されます。再生時のボリュームは特に変えたくない場合省略するか、-1を設定してください。

 

また、PlaySEに用意されている同じ曲が再生中の場合は再生しないという項目なのですが、サウンドマネージャーに用意されているAudioSourceを調べて同一曲が再生中は新たに再生しないという機能です。

この場合、再生中の定義isPlayingというAudioSourceに用意されている再生中を表すプロパティ再生時間を判別して判断しています。音楽データの最後に無音の空白が存在した場合は対処できませんので、ご了承下さい。

 

主な使い所としては、重複させたくないSEの再生時にお使いください

 

メリット・デメリット

メリット

  • ニックネームもしくはファイル名から再生できるので呼び出しが楽
  • 一斉にBGMとSEの再生停止ができる
  • 音楽データごとに音量を設定できるので音量のリマスタリングが必要ない
  • ニックネームを登録しておけば音楽データの差し替えが楽
  • どこからでも一行だけでサウンドを呼び出せる
  • 音楽データの登録方法が直感的で分かりやすい

 

デメリット

  • 現段階では、音楽のフェードに非対応
  • 別オブジェクトにアタッチされているAudioSourceの管理ができない

 

最後に

多機能なので紹介も長くなりましたが、非常に便利なので是非ご活用ください。

ソースコードの改変は自由なので、足りない機能や修正があれば追加していただいても構いません。

 

長い記事となりましたが、最後までお読み頂きありがとうございました。

最後にソースコードへのリンクがあります。

 

ソースコードのリンク

このソースコードをコピーして、新たなC#スクリプトファイルを作成し、そこにペーストしてください。

gistc0e25f522e8eb41954438992e15fb71d