ADX+UE5で、オブジェクトごとに様々な状況の効果音を手軽に設定する

# はじめに
ADXアンバサダーのSigと申します。
アンリアルエンジンとサウンドミドルウェア「ADX for UE」を連携させ、「**オブジェクトごとに『スポーン時』『衝突時』などに個別の効果音を手軽に設定する**」実装を行います。



# 前提

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

なお、ADX2は「ADX」へ名称が変更になりましたが、ツール構成は変更ありません（2がないから古いほう、というわけではありません）。

記事執筆時点のADX for UEのSDKバージョンはADX LE UE SDK(1.31.00.01)です。

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

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

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

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


# 実装

## AtomCraftで様々な効果音を用意する
AtomCraftを使い、UEに持っていくためのサウンドを構成します。

### マテリアルの用意
まずは素材となるサウンドを用意し、マテリアルとしてAtomCraftにインポートします。
音源ファイルをマテリアルツリーにドラッグ＆ドロップしましょう。
![A01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/3358e545-689b-7087-7952-0b5c6ba1d2c9.png)
今回はオブジェクトの「スポーン時」「破壊時」「衝突時」「被ダメージ時」それぞれに効果音を用意します。
オブジェクトA,B,Cにおいて、3タイプの効果音を一通り準備しました。
また、それぞれのオブジェクトごとにフォルダ分けをしています。


### キューの作成
効果音ごとにキューを作成します。
「新規オブジェクト」→「キュー『ポリフォニック』の作成」を選択してキューを新規に作成します。
![A02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d0576a24-79fb-b5b6-2451-d7ed1b9bd29f.png)
キューに名前をつけます。
![A03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/46e765a5-35cb-8d47-c98b-6161a1722fe3.png)

……という流れでもいいのですが……！
効果音単体のキューを作る場合、マテリアルツリーからドラッグ＆ドロップするだけでキューが完成します。
![A04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/75aed174-b627-295e-fdc1-d41d457d4f60.png)
シンプルなキューができました。
![A05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0120e4bf-59d4-dc55-f593-980bedecdc1e.png)
複数選択してドラッグ＆ドロップすることで、一気にキューを作っていくことができます。
![A06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c39081a1-1e02-c3b5-7ee1-a31e5a566e37.png)
お手軽にキューを量産できました。
![A07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a842e758-628c-2103-a965-975e6595ee14.png)
距離減衰をUE内で実現するため、キュー内の「パンタイプ」を「3Dポジショニング」に設定します。
![A08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/4abae4c8-1a7d-7bce-779c-4e1be5090522.png)



### キューシートのビルド
キューが用意できたら、キューシートをビルドします。
![A09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ebb884f8-b795-59db-36e9-f6897d6e21ca.png)
![A10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d54e8343-f795-185c-60ad-b0769c83c5c8.png)



## UEで効果音を設定・再生する

### キューシートのインポート
ビルドしたacbファイル、acfファイルをUEのコンテンツブラウザの任意の場所にドラッグ＆ドロップしインポートします。
![B01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/76f26b0f-9d38-2bc6-9a9c-ca75a10eea4f.png)
すべてのキューが正しくインポートされていることを確認します。
![B02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/7b0e18cb-68b1-7d97-0f08-96fdcb96a312.png)


ツールバーの「Edit」→「Project Settings」からプロジェクト設定を開き、
![B03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/6f991d55-dd54-5c39-df17-98162159e56e.png)
「CriWare」タブ、Atom Configの項目に今回インポートしたacfファイルを指定します。
![B04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/74400cba-9384-4c1a-f1a0-f362fd7d9c70.png)


### 構造体を作成・設定する

オブジェクトごとに手軽に効果音を設定するために、「どの状況でどの効果音を鳴らすか」というテンプレートが欲しいところです。そこで、規格となる**構造体**（Structure）を作成しましょう。
コンテンツブラウザの任意の場所で右クリックし、「Blueprints」→「Structure」を選択。
![B05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/60fe243e-228a-92fb-ce2a-06c865a3c456.png)
構造体（Structure）が作成されました。
![B06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9873dea8-98dc-b5a5-aa7b-8e80bef9ebd4.png)
ダブルクリックして開きます。
![B07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/22af153e-c62e-fd94-f1be-f3e42fb6bbba.png)
変数に名前をつけ、型を「Sound Atom Cue」→「Object Reference」に設定します。
![B08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8e9585a1-1e8a-8058-43ff-4c05d6025199.png)
「+Add Variable」ボタンを押し、変数を追加します。
![B09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/dcad4f3a-5089-18fe-85e1-dcaf6107b064.png)
新たな変数に名前をつけます。型が「Sound Atom Cue」になっていることを確認しておきましょう。
![B10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/438626b2-020e-d960-944c-2a27331bff4f.png)
「SpawnSound」「DamageSound」「HitSound」「DestroySound」を追加します。
![B11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/68a1d84b-1782-6fa9-c0a8-0ee53415fd89.png)
これで、この構造体は4つの変数を内包するようになりました。
あとはこの構造体をBPアクター側から分解し、取得して再生するだけです。


### 構造体のパラメータを参照して再生する

オブジェクト側の処理を書いていきます。
コンテンツブラウザの任意の場所でアクターを作成します。

「Blueprint Class」を選んで作成します。
![C01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a6be2bcb-0c9f-df62-095b-77fae297eabc.png)
親クラスは「Actor」とします。
![C02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f02e2680-c245-2fb0-3348-dcc2da1f8a7b.png)
作成されたアクターに名前をつけます。このアクターをベースとして、様々な見た目や効果音にカスタマイズします。
![C03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/372537fb-2c99-91fe-1940-b996bdacdc1a.png)
ダブルクリックして開きます。
「StaticMesh」コンポーネントを作成します。
![C04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f7bb2f18-82eb-1760-d053-f12a0a653e0d.png)
「StaticMesh」コンポーネントには、仮のモデルとマテリアルを指定しておきます。
![C05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d1e98ce1-217a-e258-3130-c22f0b09b196.png)

イベントグラフに移動します。
変数を新規に追加します。
![C06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/5abacc62-97e3-da38-6bd2-5e8c8cf4fee4.png)
変数に名前をつけます。
![C07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0c632780-b8d0-5a97-5552-d42de8163997.png)
Variable Typeには先ほど作って設定した「Str_ObjectSound」を選択します。
![C08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f0ec06da-ecbc-ad56-d136-0880379c12ea.png)
コンパイルすると、Atom Cueが設定できるようになります。
![C09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9ebc6c72-0c55-d15b-3965-cef22de998b4.png)
仮として、デフォルトのサウンドを設定します。
![C10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a120563d-e5d3-ba79-61bf-2aaeea1a0420.png)
「Instance Editable」にチェックを入れ、外部から編集可能にしておきます。
レベル上でビューポートから個別にサウンドを指定できるようになります。
![C11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/76206fd9-c0fa-9ed0-a1d8-6010a20fa72c.png)

イベントグラフに処理を書いていきましょう。
構造体からの値は、**Get （構造体名）ノード**から線を伸ばし、**Break （構造体名）ノード**で取得できます。
![C12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1b05cc4b-f68a-1744-35b5-53f588f96506.png)
サウンドの再生は**Spawn Atom Sound at Location**で行います。
これだけで、スポーン時のサウンドが再生できます。
![C13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/80b79e36-eaf4-2195-9b0b-07354216dceb.png)
衝突時のサウンドを再生するため、StaticMeshコンポーネントの「Simulate Physics」にチェックを入れ、物理挙動をONにしておきます。
![C14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/60816a0c-924e-5bba-5a09-0a5b8cb9a5ed.png)
StaticMeshアクターの「Add Event」から、「Add On ComponentHit」を選択。
![C15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ed71bacb-6448-8eac-d20c-73afdda45544.png)
衝突時のイベントが作られるので、そこからサウンドの再生を行います。
**Break Str_ObjectSound**ノードからの参照は「HitSound」です。
![C16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/20d7b066-4e0b-53d8-cfd4-89c88d388c21.png)
また、**Event AnyDamage**イベントから「DamageSound」を再生し、
![C17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f324ed68-49bf-95d5-7285-c3baf9997cb9.png)
**Event Destroyed**イベントから「DestroySound」を再生すればOKです。
![C18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f2d9bcd7-4c82-7865-03ff-d888be61f998.png)
これで、スポーン時や衝突時、被ダメージ時やデストロイ時にサウンドが再生されるようになりました。
![C19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8718a170-1c8f-58c9-a24d-edb29b735c07.png)
サウンドの再生を確認するには、コンソールコマンド「cri.ShowSoundLocation 1」で視覚化できます。
![C20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/76e38913-a789-25ab-fa61-ec059d411f55.png)

レベル上のアクターを複製し、Detailsパネルから「ObjectSoundList」を編集すれば、再生するサウンドを変更できます。
![C21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/35ec9a09-5ccc-53d3-5fd2-0e262d911790.png)
また、Detailsパネルの「StaticMesh」コンポーネントを選択すると、メッシュの見た目やマテリアル、各種物理パラメータなどが個別に設定できます。
![C22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e9cbc014-8f73-b374-8b3a-c94c4f71f2f7.png)
こちらも再生して、挙動が正しいことを確認してみましょう。
![C23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9a079616-1403-95ac-b162-a88b8491f918.png)
こうして、シンプルなオブジェクトとその物理挙動、またその際のサウンド再生が手軽に再生できるようになります。
ゲームのステージ上に配置し、世界観を盛り上げる小道具として役立ちそうです。


今回作成したアクターはごくごくシンプルな構造をしていますので、カスタマイズの余地が大幅にあります。
このクラスを継承して新たな機能を持つアクターを作ってもいいですし、また構造体をデータテーブルに登録して外部のスプレッドシートから音源を取得することも可能です。