UE5 + ADXで、遠距離や遮蔽物に隠れた音を減衰させる（オクルージョン）

# はじめに
ADXアンバサダーとして記事を書いておりますSigと申します。
この記事ではアンリアルエンジン5とサウンドミドルウェア「ADX for UE」を連携させ、**ゲーム中に音源が遮蔽物に隠れた際、聞こえてくる音を減衰**させます。
単純な音量の変化だけでなく、音をくぐもったように変化させて臨場感を与えることも可能です。

https://twitter.com/sleepyslowsheep/status/1425373924607496197?s=20

ADXによってUEに追加されるサウンド機能の「オクルージョン」を使用します。


当記事ではUE5.2を使用します。基本的にブループリントのみでの実装を想定しています。
ADX for UEはインディー向けの「LE版」であれば、無料で使用できます。
https://game.criware.jp/products/adx-le/

# 前提
ADX for UEの導入や基本的な使い方は以下の記事にあります。必要に応じて参照してください。
**ADX for UEの導入で、一歩上のサウンド表現を（導入編）**

https://qiita.com/SigRem/items/4250925f6d66a4fd287a

**ADX for UEの導入で、一歩上のサウンド表現を（実践編）**

https://qiita.com/SigRem/items/c089b71c42e898980a46

# 実装

## AtomCraftでサウンドを用意する

### マテリアルの用意
AtomCraftでサウンド及びキューシートをビルドします。
サンプルとしてBGMと喧騒の環境音を用意してみました。
![A01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0b08f08f-3135-eafc-c284-7b44b3fb7f5f.png)

マテリアルにはループ設定をしておきます。マテリアルを選択した状態で、インスペクターにて「ループ情報の上書き」を**「True」**に、「ループタイプ」を**「ループ」**に設定します。
![A02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/33275c0c-2ab3-b0aa-7660-0309d7631863.png)


### キューを作成する
今回AtomCraftで特別な実装は必要ないので、キューシートを右クリックし「新規オブジェクト」→「キュー『ポリフォニック』の作成」で通常どおりキューを用意します。
![A03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/cb2125c8-3741-be15-9b8b-1c61d592ff37.png)
![A04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1bd13ff2-bd9e-54d9-1bad-a4fbca122aaf.png)

それぞれ対応したマテリアルを配置し、テスト再生して確認してみましょう。
![A05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/da5d788b-8d28-18e7-8cd2-93f4831bda63.png)


### キューシートをビルドする
キューが完成したらキューシートを書き出します。
![A06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1b7a4394-56c5-75c4-8a0f-a1531fbf5356.png)
![A07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/73d97d21-34d3-2275-b107-9f94d1380b23.png)



## UE5でオクルージョンの設定をする

### キューシートのインポート
UE4エディタを起動し、ビルドしたacbファイル、acfファイルをインポートします。

acfファイルのインポート時のダイアログでは、どちらも「Yes」を選択します。
これにより、ビルドしたacfファイルがUE5のプロジェクトに適用されます。
![A01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f47e9abe-5d2e-0662-6e71-74250e5eb875.png)
![A02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0fba8dc7-ad00-db9f-51d9-a2b2e0ecfed4.png)

アセットがふたつともインポートされたことを確認します。
![A03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8bcd6580-9eba-a44d-b94d-1d200efcdda5.png)

キューシートのアセットを開き、キューが正常にインポートされているか確認しておくといいでしょう。
![A04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/183ad16b-7c41-ede2-baad-9762f295fc6f.png)



## レベル上からキューのAttenuationを設定する
キューのAttenuation（減衰）設定をします。

レベル上に任意のキューを配置します。
鳴らし続けて動作を確認したいので、ループして再生されるキューが最適です。
![B01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a4a1d6ae-736f-e5a7-b2c3-0d5d521d63e4.png)


レベル上に配置したキューを選択し、Detailsパネルにて「Override Attenuation」にチェックを入れます。
![B02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0d71ed0f-700a-b659-c8ab-eca674cf2b57.png)

チェックを入れると、距離などによる減衰が設定できる項目が出現します。
![B03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f1a531cc-3f29-c9c5-90d2-a9eebbe6340b.png)

チェックを入れない場合AtomCraftで設定した減衰設定が、「Attenuation Settings」にUE4で作成した減衰設定を適用した場合それが適用されます。
ざっと設定項目を見ていきましょう。

### Attenuation(Volume)
リスナーと音源の距離が離れた場合の音量の減衰です。
「Enable Volume Attenuation」にチェックを入れることで有効になります。
![B04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d93bf269-4cc1-b572-611f-7c17ef521da4.png)

「Inner Radius」と「Falloff Distance」で減衰が始まる距離、聞こえなくなる距離が設定できます。
レベル上でもふたつの領域が表示されます。
![B05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/48f4753a-ca79-fcad-f73b-3500785e7022.png)

「Attenuation Shape」で減衰距離の形を変え、指向性のある減衰を設定することもできます。
![B06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b31ddf1e-5c10-9a77-028c-b71dc4ed601d.png)

項目を初期設定に戻したい場合は、矢印をクリックします。
初期値から数値が変更されたプロパティにのみ出現します。
![B07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1ff0f81c-9784-2b1d-376f-ca8df150f504.png)



### Attenuation(Spatialization)
リスナーと音源の位置により、左右に音声を割り振り3Dサウンドを演出します。
「Enable Spatialization」にチェックを入れると有効化されます。
![B08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/51b11457-47d3-5633-8c6f-15546ba7ed23.png)

「密着した状態では両側から等しく音が聞こえるが、一定距離離れると3Dサウンドとして聞こえる」といった設定も可能です。
![B09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f56bf06b-c329-0188-d938-5044a57350dc.png)



### Attenuation(Occlusion)
「Occulusion」では、遮蔽物に隠れた場合の設定ができます。
「Enable Occlusion」にチェックを入れて有効化します。
![B10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/063cf156-61e1-f007-8ca7-1f0c53713f63.png)

**Occlusion Low Pass Filter Frequency**では、隠れた音の高音部分をカットしてくぐもった印象にさせます。
数値で指定した以上の音域が聞こえなくなります。
この数値を小さめにし、BGMなどを再生してみると違いが分かりやすいです。
**Occlusion Volume Attenuation**は隠れた音の音量を小さくする設定です。

ゲームを実行してみましょう。カメラから見て壁の向こうに音が隠れた際、音が小さく、くぐもるように変化するはずです。
![B11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e984429f-50d0-bd6a-2a12-0a7c8691da51.png)

※テスト用に音源を描画しています。コンソールコマンド「atom.3dVisulalize.Enabled 1」を入力することで音源が可視化されます。
![B12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/3ea4cf50-c41c-738e-c0f8-cb2e2649ba6d.png)




「**Occlusion Interpolation Time**」は減衰状態、通常状態に移行するのにかかる時間の設定です。
「0.5」などの大きめの数値にしてテストしてみると分かりやすいでしょう。
![B13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/37efda51-ec75-2af4-b724-d3fb2ad76822.png)


「**Occlusion Trace Channel**」は遮蔽物を判定するためのTrace Channelです。
「Pawn」にすると、原則としてキャラクターのみが遮蔽物として判定されます。通常は「Visibility」で使うことになるでしょう。
![B14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ae1fcb0a-2689-4861-489f-dfad023d9245.png)

アクターやコンポーネントの「Collision」の項でチャンネルが有効かどうか個別に設定できます。
![B15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/5e583d30-7b5f-3cbc-6100-32683477e188.png)


Trace Channelを追加したり、設定を変更するにはツールバーの「Edit」→「Project Settings」からプロジェクト設定を開きます。
![B16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/41a4ce39-e46d-cd37-23ba-c0d5c084fb82.png)

「Collision」タブで既存のTrace Channelを編集したり新しく追加することが可能です。
![B17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/bb51828b-e75d-a828-8ad0-bebd9e271b16.png)
サウンド用にTrace Channelを追加しても便利かもしれません。



## Atom Attenuationアセットを使い、多数のキューにオクルージョンの設定を適用する

上記の方法は一点ものの音源に対しては有効ですが、レベル上の多数のキューに対していちいちこういった設定をしていくのは面倒ですね。
そこでADX for UEの新バージョンで追加された**Atom Attenuation**アセットを使用すれば、よく使用する減衰設定をアセットとして保持しておき、多数のキューにワンタッチで適用することが可能です。

Atom Attenuationアセットを作るには、コンテンツブラウザ（コンテンツドロワー）で右クリックし、
「ADX Atom」→「Spatialization」→「Atom Attenuation」を選択します。
![C01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/44abbd6f-0abe-c1b5-6c5f-e8f6908997f2.png)
アセットが作られるので、適当な名前をつけます。
![C02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/433a1f67-add4-6cd2-b40c-cd3fb2425978.png)
ダブルクリックして開くと、通常のキューにも設定できる減衰設定が開きます。
![C03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8049fd22-91b5-22ed-d63b-9d47cca05595.png)
このアセットで設定した減衰は、キューのプロパティ「Attenuation Settings」に指定することで適用されます。
![C04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/437ca168-9e1f-3627-58a0-79fb54449aae.png)

また、キューシート上からキューに予め設定しておくことも可能です。
用途に応じて設定しておきましょう。
![C05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/627279da-e551-c454-9fee-d99d62b57a4a.png)



## 補足

### 補足：リスナー位置の設定
カメラとプレイヤーキャラクターの位置が異なる場合、「キャラクターは移動していないのにカメラを動かしたら音が隠れた扱いになる」現象が起こることがあります。
**Set Audio Listener Override**ノードを使うことで、音の遮蔽判定をどこで行うのか設定できます。
![D01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d1b5c0a1-c304-1ac6-252b-96e630227afc.png)

コンポーネントを指定すると、そのコンポーネントにリスナーの座標が追従します。
![D02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c7cb3d86-b10c-98a3-1abd-337c9cea4696.png)
![D03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/2b4897de-b757-00ea-7382-de3d7d393209.png)

リスナーの位置を可視化するには、コンソールコマンド「atom.3dVisualize.Listeners 1」を入力します。
![D04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9e3eca11-5858-116e-4241-4ecfcd0539d4.png)