ADX2+UE4で、物理挙動にランダム性のある効果音をつける

# はじめに
UE4.23+「ADX2 LE v2.10.05」を使用します。
アンリアルエンジン4とサウンドミドルウェア「ADX2 for UE4」を連携させ、
ゲーム中のオブジェクトが落ちたり転がったりして、ぶつかった際に様々な音がランダムに再生され、また衝撃の状況により変化が出るようにしてみます。

## 今回の実装例
UE4標準の「Physics Simulation」を有効にすることにより物理挙動は簡単に実装できます。
衝撃の際、どれだけ大きな力がかかったか、また物体の重さにより音が変化する実装をします。
![A00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/41861135-ef7d-49da-0c1e-761d4ea3ec15.png)


# 前提
「ADX2 for UE4 LE」を使用します。導入や簡単な使い方は以下の記事にあります。
ADX2 for UE4の導入で、一歩上のサウンド表現を（導入編）
https://qiita.com/SigRem/items/4250925f6d66a4fd287a
ADX2 for UE4の導入で、一歩上のサウンド表現を（実践編）
https://qiita.com/SigRem/items/c089b71c42e898980a46


#やること
- AtomCraftでキューを作成
- パラメータを調整し、音に性質を追加する
- UE4にインポート
- Physicsの調整
- ブループリントで、サウンド処理を実装する


# 実装

##AtomCraft側

###素材の用意
いくつかの衝撃音が必要になります。
マーケットプレイスでもいい感じの音が仕入れられるので、アテがない方はチェックしてみるといいでしょう。
![A01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/3e13f4d6-b12d-f9e7-bf1f-a2cf1b3929cc.png)
ものが落ちる音が数パターンあれば大丈夫です。
用意できたら、マテリアルツリー内にインポートします。
今回は通常の衝撃音3種＋強い衝突が起こった際の音を1種用意しました。
![A02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/cd0dc8e7-753f-e571-1db3-3414cc3c11e7.png)



###キューの作成
Atomキューを作成します。
今回は「新規オブジェクト」→**「キュー『ランダムノーリピート』の作成」**を選びます。
「ランダムノーリピート」のキューでは、各トラックがランダムに再生されます。
「ランダム」のキューと異なり、直前に再生された音以外が再生されるので音のばらつきを表現したい場合に使うといいでしょう。
![A03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/31c5423e-117d-5318-8cce-4b10258a4ff0.png)
作成したキューに分かりやすい名前をつけます。
![A04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ce5ccf2e-920d-3040-6a59-cdc7e4e6365a.png)
用意したサウンド素材をマテリアルツリーからドラッグアンドドロップしてトラックを作ります。
![A05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/00818230-b9fb-cb62-5b32-0dc017afed3a.png)
![A06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/dad3a204-7d13-105c-46ad-65fa9aa465fa.png)
この時点で再生ボタンを押すと、4つのトラックからどれかが再生されます。
大きな衝撃が起こった際の音のためのキューも作ります。こちらも「ランダムノーリピート」で作りました。

トラックはひとつしかないため、常に1種の音から再生されます。


###キューの設定
再生に必要なキューの設定をします。
「ランダム」や「ランダムノーリピート」キューでは、トラックを選択した状態でインスペクターの「確率」をいじるとトラックの再生確率を変えることができます。
![A07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ee9c927a-2b38-3202-776e-142508da70cc.png)


###ピッチやパンニング（聞こえる方向）にもランダム性をもたせる
さらに、キューの設定により聞こえ方にランダム性をもたせることもできます。
キューを選択し、インスペクターにてボリュームとピッチをランダム幅を設定します。
![A10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/13df8ea0-9d6f-7607-70a4-66daf948c215.png)
同じ用に聞こえる方向や角度にもランダム幅を設定できます。
![A11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e1488eb4-ab26-0d94-c2f0-b9d6f2e66a2e.png)
これらはキューだけでなく、トラックに対して設定することも可能です。


###キューシートのビルド
サウンドが完成したら、キューシートをビルドします。
![A08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b431d40d-fb39-bead-cd34-a0cc4a8b07e7.png)
![A09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/4faacc96-6487-a3d3-4434-943dcc93827c.png)


##UE4側の実装
Unreal Editorに移ります。
###サウンドのインポート
ビルドしたキューシートをインポートします。
![B01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8dae9b9d-a9b7-336f-45cd-42f9701702d7.png)
Project Settingsの「Atom Config」が正しい（今回作成されたもの）か確認しておきましょう。
![B02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e2efdc73-5069-48e9-06b4-d46d150c9291.png)

インポートしたAtom Cueをダブルクリックして開きます。
UE4上で3D空間上でのサウンド減衰を設定するには、Sound Attenuationを設定します。
![B20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/3ac02f04-dccb-22a0-24db-27203f889f20.png)
もし該当ファイルがない場合、「Create New Asset」で作成することができます。
![B21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/6e84a2c9-4f3c-7d6e-9783-4d85d3054fc2.png)


###アクターのセットアップ
物理挙動が働くオブジェクトとなる新規アクターを作成します。
コンテンツブラウザで右クリックし、「Blueprint Class」を選びます。
![B03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/df6c1e88-978d-e1ec-8975-37bfc61074a6.png)
クラスは「Actor」を選択します。
![B04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e69fe9ce-5cb4-5da0-9072-010df08db30e.png)
分かりやすい名前を付けます。
![B05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f7b76dda-27d1-18b5-3a37-4d1f4633d088.png)

作成したアクターをダブルクリックして開きます。
「+Add Component」から「Cube」を追加します。
![B06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/2cc6326c-57c9-01fb-1b95-8de3c3aa0263.png)
とりあえずはこれがアクターが持つ「物体」になります。
![B07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/2dd93f6f-fe53-5a93-7c6d-c25ab64951a3.png)
Detailsパネルの「Simulate Physics」にチェックを入れると物理演算が有効になります。
![B08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a1ba090c-9af3-77d2-aa53-5759ed10c93f.png)


###Physics設定
Detailsパネルの「Physics」では、物理挙動を細かく設定することができます。
![B23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/cd1e54b5-38bc-b954-7def-594e24215088.png)
パラメータについての詳しい解説は、公式のドキュメントを参照するといいかもしれません。

**物理ボディ リファレンス**
https://docs.unrealengine.com/ja/Engine/Physics/PhysicsBodies/Reference/index.html


###ブループリントで衝撃時に音を出す
アクターのイベントグラフに移動し、処理を書いていきます。
![B09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/dea62570-93af-6cc2-c1aa-29fb1079fab2.png)
Componentsパネルの「Cube」をドラッグアンドドロップし、リファレンスノードを置きます。
![B10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/57677a0b-76b1-c15b-fb52-762bd3964b7a.png)
**Cube**ノードから線を伸ばし、**Set Notify Rigid Body Collision**ノードを配置します。
![B11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ae73c043-8f8d-7e8e-0e7c-6e6a085b8a2a.png)
これにより、物理演算による衝突時にイベントが発行されます。
![B12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/faac2813-a9b0-e589-ed50-959542b37189.png)
Componentsパネルの「Cube」を右クリックし、「Add Event」→「Add OnComponentHit」をクリックします。
![B13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ff32b3a8-cc38-cd66-7f94-2ac54360576a.png)
**On Component Hit**イベントが作成されました。
![B14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/3f4c2519-b29f-c719-3eeb-5375c9db8911.png)
衝突に関する情報を取るため、「Hit」ピンから線を伸ばして**Break Hit Result**ノードを置きます。
![B15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/dbbbdd6a-0b54-e63a-dc90-a3b24bd36eb6.png)
このノードから衝突した場所、もの、角度など様々な情報が取れます。
![B16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/201a4f0d-1b1c-54aa-5d4e-b293e4df8819.png)
**Play Sound at Location**を置きます。Atomカテゴリの方です。
![B17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/6f98ef15-c4b4-5433-bc28-3e99930fbf2d.png)
**Break Hit Result**の「Location」ピンをつなげ、再生するAtom Cueを指定します。
![B18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/747147fa-031d-0638-c898-08ebdd8ca71d.png)

とりあえず音は鳴ります。この状態で試しにゲームを再生すると……　**試す場合は音量注意**
![B24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/21885d2e-3eb1-950c-342d-6c5078d1a93b.png)
サウンドは再生されますが、物体が静止したように見えても細かな振動で再生されてしまいます。
衝撃が一定以上の大きさのときのみ音が出るよう、改善を加えてみたほうがよさそうです。

###衝撃の大きさによる再生制限をかける
衝撃の大きさはHitイベントの「Normal Impulse」から**VectorLength**をかければ取得することができます。
![B19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c0768a76-5832-920f-fff9-b520e082b87e.png)
上記のように、一定値以上だったら音が鳴るよう**Branch**を挟むといいでしょう。


###衝撃の大きさにより音を変化させる

他にも、物体の重さを考慮して計算に入れるのも面白いかも。重さは物理演算が有効なコンポーネントに対して「Get Mass」で取得することができます。
![B22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/4115877d-9771-4aca-0fbd-a0932e995c2f.png)