Unity連携編.02 / 3Dサウンド(距離減衰)の設定方法
距離減衰とは、音源とカメラ(リスナー)との距離によって音の大きさが変わる演出のことです。
遠くのオブジェクトが発生する音は小さく、近くのオブジェクトからは大きく聞こえるようになります。
Unity標準オーディオでは、AudioSourceコンポーネントの「Spatial Blend」項目で3Dポジショニング設定ができました。
この数値を設定しておけば、AudioListenerとAudioSourceの位置関係によって音量がいい感じに変化します。
ADX2の場合は、サウンドのデータ側(キュー)に3Dポジショニングの設定をするアプローチで設定します。
その方法は2種類ありますので、順を追って解説します。
方法1:3Dポジショニング設定を使う
一番シンプルな方法としては、「3Dポジショニング」の設定を行う事です。
メートル単位で設定した最小値~最大値の間で距離の変化に応じて減衰する演出を作ることができます。
AtomCraft側の設定
まずは、3Dポジショニング設定をしたいキューのウェーブフォームを選択し、インスペクターのパンタイプ選択で「3Dポジショニング」を選びます。
次に、キューのインスペクターにあるパン[3D]設定で、距離減衰の最大値と最小値を設定します。
(画像の例では、巨大ロボットゲームかつカメラが高い位置にある場合の設定なので、数値がすごい大きいです)
Unity Editor側の設定
Editor側のCriAtomSourceでは、特に設定は必要ありません。
ただし、CriAtomListenerをシーンに配置する必要になります。これは、Unity標準で言うところのAudioListenerと同じ働きをするコンポーネントです。
通常は、現在有効なカメラの位置にAtomListenerをアタッチします。
演出などでカメラが激しく変わるゲームの場合は、独立したゲームオブジェクトとして扱い、位置を更新する管理方法がおすすめです。
CriAtomSourceコンポーネントでは、「3D Positioning」オプションにチェックを入れます。
これで準備完了です。
Unity内でAtomSourceの位置を動かしてみて、設定した距離減衰が行われているか確認してみてください。
距離減衰のデザインをAISACで行う
デフォルト設定では、距離に応じた減衰のさせ方が直線的な処理になります。また、「減衰最大」時には音量がゼロになります。
距離による減衰のさせ方を細かく設定したい場合は、AISAC機能を使って設定することが可能です。
AISACとは、ゲームと連動してリアルタイムに変化する音を制御するためのシステムです。
乗り物などのエンジンがスピードに合わせて変化する音や、ゲームの盛り上がりに連動したスタジアムの歓声等を作ることができます。
実体は下記のようなグラフで、各トラックごとのボリュームやピッチ、パンニング、フィルタなどの変化を設定できます。
グラフは0から1までの数値で、指定のパラメーターがどのように変化するかを表現します。
上の例では、0~0.8までゆるやかにボリュームが小さくなった後、0.8~1までは変化しない、というグラフになります。
これは、対象物がある程度遠くなった時はどれだけ離れても小さく音はなり続ける、という表現になります。
「3Dポジショニング」には、距離減衰の最小値から最大値をAISACの0~1に割り当てる機能があります。これを使って、減衰のさせ方を自由に設定するアプローチです。
AtomCraft側の設定
AISACの設定をする前に、AISACの0から1までの数値変化を設定するための「AISACコントロールID」について確認します。
プログラムやツール内でAISACを操作するには、この「AISACコントロールID」を指定して、紐づいているAISACの値を一斉に操作します。
AISACコントロールIDは、プロジェクトツリーで設定します。
デフォルトでは16個のコントロールIDがあります。どれでもいいので、距離減衰用のコントロールIDとして「Distance」という名前に変更しましょう。
AISACコントロールIDを準備したら、AISACグラフ側を作ります。
AISACには、キューごとに設定する通常の「AISAC」と、同一プロジェクトで再利用可能な「グローバルAISAC」の2種類があります。
グローバルAISACは、複数のキューで使うことができる、テンプレートのようなものです。
距離減衰の表現は様々な音で使いそうなので、グローバルAISACで設定をしてみましょう。
プロジェクトツリーを開き、「グローバルAISAC」の項目で右クリックをして「AISACの作成」を選びます。
今回は距離減衰用のAISACなので、「Distance」という名前にしておきます。
AISACコントロール(ID:名前)欄に、さきほど設定した「Distance」をセットします。
距離減衰はボリュームを操作するものですので、AISACグラフタイプは「ボリューム」を選びます。
新規作成された「Distance」AISACをクリックして、カーブを編集します。
線の上でクリックするとポイントを増やすことができ、ドラッグで動かします。
この時、右クリックから「カーブタイプ」を「低速変化」にすると、次のような滑らかなカーブを作成することができます。
設定が終わったら、作成したグローバルAISAC設定を距離減衰を行うキューへドラッグアンドドロップします。
キューの「パン[3D]」項目で、AISACコントロールの「距離」にDistanceを設定します。
この設定で、ADX2が自動的に計算する距離減衰の値が、AISACのコントロールに使用されるようになります。
ボリュームだけでなく、遠くなったら残響を加える…という効果もこの手法で適用可能です。
方法2:AISACのみを使う
「3Dポジショニング」を使わずに、Unity側から直接AISACの値を調整する方法もあります。
たとえば、固定カメラ視点の対戦ゲームを考えてみてください。
カメラが斜め上空からステージを見下ろしており、プレイヤーが奥へ行ったときに足音や声などが小さくなる効果を作りたいとします。
「3Dポジショニング」機能を使って、リスナーからの距離で距離減衰を表現してもよいのですが、固定カメラ視点ゲームの場合、カメラ位置は上空にあります。
CriAtomListenerとAtomSourceの距離に関係なく、「プレイヤーの奥行方向の位置」情報で距離減衰をしたい場合もありえます。
その際は、3Dポジショニングをオフにして、AISACコントロールを直接操作するアプローチをとります。
プレイヤーがもっとも手前に居る位置を0、奥に行き切った座標を1として設定し、ゲーム中はプレイヤーの位置情報によってAISACをコントロールできます。
AtomCraft側の設定
対象のキューの中のウェーブフォームで、パン設定を「パン3D」に戻します。
また、キュー設定のパン[3D]」項目で設定したAISACコントロールの「距離」を「なし」に戻します。
UnityEditor側の設定
まず、CriAtomSourceコンポーネントの3D Positioningをオフにします。
次に、AISAC値を操作するスクリプトを用意します。
スクリプトはシンプルです。操作したいキューを再生するCriAtomSourceコンポーネントに対し、SetAisacControl関数でAISAC値を与えるだけです。
public void SetDistanceControlValue(float value)
{
criAtomSource.SetAisacControl(“Distance”, value);
}
ただし、ゲームから距離に関する情報を0~1の値に変換して上記関数に渡す必要があります。
先ほどの図の例では、ステージの奥行サイズとプレイヤーの現在座標から導き出す計算になります。
個々はゲームの構造によって全く違うので、開発者自身が考えなくてはなりません。
どちらの方法を取るか?
3Dポジショニング機能を使った距離減衰はAtomCraftとUnity両方で所定の部分にチェックを入れていくだけなので設定が簡単です。
また、AISACをあわせて使うことで、減衰のさせ具合を細かくデザインできます。
実は、AISACを使用するとテーブルの参照等によるわずかなCPU負荷が加わります。負荷といっても、一般的なノートPCで50音同時に鳴らしたとしても1パーセント未満しか変わりません。
モバイルで負荷コントロールがカツカツの場合、かつ大量に音が鳴る場合は気に留めておくとよいでしょう。
AISACのみを使う方法は、距離情報を自分で計算し、都度AISACコントロール値を操作する必要があります。
かわりに、Unity側で距離減衰の条件を自由に設計できます。
両方式を同じプロジェクトで共存させることもできるので、まず3Dポジショニングを使って、操作しづらい場面にあたったらAISACの直接コントロールを検証してみましょう。