ADX + UE5でゲーム中のヒットサウンドを多機能に実装する（新バージョン対応版）

# はじめに
ADXアンバサダーとして記事を書いておりますSigと申します。
この記事ではアンリアルエンジン5とサウンドミドルウェア「ADX for UE」を使って、ゲーム中の攻撃などのヒットサウンドを多機能に実装してみます。

ADX for UEの新バージョンにて、「ゲーム変数」機能に対応したため、UE5でも同様の実装ができるようになりました。
記事と同様の実装を行えば、ADX旧バージョンでも同じ処理が実装可能です（一部ノード名などが変化しています）。

当記事ではUE5.3を使用します。基本的にブループリントのみでの実装を想定しています。
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で効果音を構成する

### マテリアルの用意

今回は3連の打撃を1コンボとし、それぞれの打撃に弱・中・強の3段階の音を用意しました。
合計9つのマテリアルになります。
![A01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b4363868-3e99-7f3d-ceab-0b4ba08c2ce8.png)

### キューの作成

キューシートで右クリックし、「新規オブジェクト」→「キュー『スイッチ』の作成」を選択します。
![A02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/bea8bce4-4e27-884e-2ccf-4468047d844c.png)
これがコンボ1段目のキューとなるので、トラックを分けて1段目の「弱・中・強」のマテリアルをそれぞれドラッグアンドドロップして配置します。
![A03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/03da45ea-f3ee-8a55-082a-0b6f01ed209d.png)


### ゲーム変数の設定

3つのトラックからひとつをゲーム中選択して再生するには、ADXの**「ゲーム変数」**機能を使います。
プロジェクトツリーの「ゲーム変数」で右クリックし、「新規オブジェクト」→「ゲーム変数の作成」を選びます。
![A04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b35192dc-fdfc-6f2b-ccca-bbd34fefdee0.png)
新しくゲーム変数が作られるので、適当に名前をつけます。画像では「HitStrength」としました。
![A05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/79c0378d-3036-8a11-58a6-189c68effad4.png)

キューを選択し、インスペクター中段にて「スイッチ」のボタンを押し、スイッチ変数を先ほど作成したものにします。
![A06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/6da523da-64cc-bc56-4796-a9e5321fe186.png)
![A07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f4a8cfba-0bc6-48f9-4cc3-0ad5c92dc84e.png)
「等分化」ボタンを押し、各トラックに振り分けられるゲーム変数の幅が均等になるようにします。
![A08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8a91ac94-5ef7-2254-f705-c93cef058687.png)

これで**ゲーム変数が0.0～1.0に近づくほど、ヒット時のサウンドが弱～中～強へと変化**します。

プロジェクトツリーのゲーム変数を選択し、インスペクターで「初期値」を変更すると再生されるトラックも変化します。
![A09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/db9ea550-25f1-3201-9730-a993a2a83bab.png)


### コンボ用のキューを作成

同じようにコンボ2段目、3段目のキューも作ります。
![A10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/5fb2288f-9290-f55d-a4a8-9aff3de90f49.png)

ここまで完了したら、3つのキューをまとめてコンボサウンドにするためのキューを作ります。
キューシートで右クリックし、「新規オブジェクト」→「キュー『コンボシーケンシャル』の作成」をします。
![A11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/90af07ad-371a-b74c-b237-c2c027778ff0.png)
コンボ1,2,3段目のキューをドラッグアンドドロップしてトラックに配置します。
![A12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/23e044f3-ed87-5436-47dd-cb584529651b.png)
キューそのものがトラックに登録されました。上からコンボ1,2,3段目となるよう配置します。
![A13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/fec40657-e21b-df28-8447-cb12d497f869.png)
キューは「キューリンク」という機能で呼び出されています。これはもとのキューに紐付けられているので、各キューが編集されるとコンボ用のキューにも影響を与えることになります。

インスペクターにて、「コンボ間隔」を「1000（ミリ秒）」とします。これで1秒以内に連続でキューが再生された場合、「コンボ」として異なるトラックが再生されていきます。もちろん各トラックはゲーム変数の値を反映して再生されます。
![A14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/6330129e-6a85-1abb-07a7-c23a568a838e.png)

### キューシートのビルド

ここまでできたらキューシートをビルドします。
![A15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d22c1801-4574-d6bf-1f70-07d78a21276a.png)
![A16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1296114d-a24e-685c-bdb5-538db4e54cf3.png)


## UE5での実装

### UE5にキューシートをインポートする

ビルドしたacfファイル、acbファイルをコンテンツブラウザ（コンテンツドロワー）にドラッグアンドドロップしてインポートします。
acfファイルインポート時のダイアログにはどちらも「Yes」を選択します。
これにより、プロジェクトにAtom Configファイルが自動的に設定されます。
![B01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1d8d879f-c001-0bdd-9848-b6dbbf909d16.png)
![B02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/fd12f083-7a91-d2a5-28ba-e19063bad30b.png)

Atom Config、キューシートの両アセットがプロジェクトに入っていることを確認します。
![B03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/920921ca-5843-3958-7dba-c5641a0daf41.png)
キューシートを開き、キューが再生できることを確認します。
![B04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/59c1057b-6d2c-f925-6699-2a0075987053.png)
連続でコンボキューを再生すると、この状態でもサウンドが変化します。
![B05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/05e34897-fe9c-5bbb-8c42-bcd73dabeb4b.png)



### 攻撃ヒット時にサウンドを再生する

キャラクターのブループリント内に基本的な当たり判定処理を作ってみました。
（画像をクリックすると拡大されます）
![B06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/207358a5-e9ee-5477-d271-f26765d25a48.png)

ボックス型のトレースをキャラクターから進行方向に飛ばし、対象となるトレースチャンネルにヒットすればダメージが発生するものです。
ダメージを受け渡す**Apply Damage**ノードの先に、**Spawn Sound at Location**を配置します。
![B07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/073ca625-64f6-e7b2-12c4-765f8a0ca495.png)

UE5デフォルトの同名ノードではなく、ADXによって提供されたノードを使用してください。
![B07B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/04fcc628-fe4f-6d50-5110-52d5c2a588cf.png)


**Break Hit Result**ノードの「Locaiton」ピンを使い、正確なヒット箇所（トレースがヒットした座標）に音を配置しています。処理やゲームジャンルによって、キャラクター座標に再生したり、2Dサウンドとして直接スポーンしてもいいでしょう。

次に、再生するキューを指定してあげる必要があります。
**Spawn Sound at Location**ノードの青いインプットピンを右クリックし、「Promote to Variable」で変数化します。
![B08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/113315c3-ea79-eebe-108c-2302794175e4.png)

変数には「HitSound」と名前をつけました。
![B09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e8a1e6ab-b6ba-f74e-5f10-27ce1f4c85b7.png)

**コンパイルし**、Detailsパネルにて再生するキューシートとキューを指定します。今回は「Cue_Combo」としました。
![B10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/bfb6011f-dd4f-414d-d627-afe2a33e27d8.png)



この状態でテストすると、ヒット時にキューのサウンドが再生されます。1秒以内に再ヒットすると、コンボの2段目、3段目のサウンドが再生されるでしょう。


### 打撃の強さをゲーム変数に反映する

さて、先ほどのサンプルのグラフにも出ていましたが、今回は「AttackStrength」という変数をキャラクターに持たせています。
これはそのままキャラクターの現在の攻撃の強度となりますので、この値をADX側のゲーム変数に渡してあげるとサウンドを変化させられそうです。
ヒット音を鳴らすと同時に、**Set Game Variable Value by Name**ノードを使い、ゲーム変数名と値を指定します。
（旧バージョンでは**Set Atom Game Variable**ノードでしたが、ノード名が変更されました）

名前は「HitStrength」（AtomCraftでつけた名前）、値はキャラクターの変数「AttackStrength」を代入します。
状況によって数値で補正をつけてもいいでしょう。
![B11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e9ca1882-7184-8097-407f-ff8352dd0a00.png)


テスト用に、押したボタンによって攻撃の強さが変わる処理を作ります。
次のグラフでは、**Input Key Z～C**を作りキーボードの対応ボタンを押した際に変数「Attack Strength」の値を変えています。この値がゲーム変数に反映され、ヒット時のサウンドが変化することになります。
![B12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/852cc9e8-f952-6bca-a981-2301a3b8ab81.png)



ざっとコンボ中のサウンド変化、攻撃の強弱による打ち分け機能を盛り込んでみました。
さらにAisacコントロールやバスセンドなどを使い、攻撃のヒット箇所やガード時などに音が変化する、といったことも可能です。