ADX2+UE4を使って、物理演算に材質を加味したサウンド演出

# はじめに
UE4.23+「ADX2 LE v2.10.05」を使用します。
アンリアルエンジン4とサウンドミドルウェア「ADX2 for UE4」を連携させ、
ゲーム中のオブジェクトが衝撃を受けた際、材質により音そのものや鳴らし方を変え、臨場感を高める実装についてです。

## 今回の実装例
UE4標準の「Physics Simulation」、「Physical Material」とAtomCraftのあわせ技により、衝撃面と摩擦の具合を見てサウンドに変化を加えます。衝突した材質の情報を受け取り、物体の素材ごとに違う音を出したり、柔らかい物体であれば音も鈍くなったりといったシミュレーションが可能です。

**ADX2+UE4で、物理挙動にランダム性のある効果音をつける**の発展系のような内容です。
https://qiita.com/SigRem/items/77644c292a1f3e1e16fd


# 前提
「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/fa5db59e-b894-e704-6318-5f2351866718.png)


###キューの作成
新規にAtomキューを作成します。様々なトラックからひとつを状況に合わせて再生させたいので、**キュー「スイッチ」の作成**を選択します。
![A02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/386ac91a-3469-5466-0020-b53ff9bc8e26.png)
ワークユニットツリーにキューが作成されるので、適当な名前に変更します。
![A03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/64dad44d-581c-f18e-7182-c1bd6ad9474d.png)
各サウンドをトラックに分け、ひとつずつキューに入れます。
![A04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/4e8b0207-99c9-2b2a-68b2-19b2196b5804.png)


###セレクタの作成
実行中のゲームから材質情報を受け取るために、「セレクタ」及び「セレクタラベル」を作成し、設定します。
プロジェクトツリーの「セレクタフォルダ」を右クリックし、「新規オブジェクト」→「セレクタの作成」をします。
![A05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1925008d-7ed2-96c5-09ca-6579a041f285.png)
今回は「Selector_Physics」と名付けます。
![A06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/7db701ea-fd88-17e7-20ca-4dd1c6af267d.png)
作成したセレクタを右クリックし、「新規オブジェクト」→「セレクタラベルの作成」をクリックします。
![A07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ce5a8bdc-bdf2-4c65-cf22-8a670c66dc32.png)
ひとつめには「Default」と名前をつけます。チェックはつけたままにしてください。セレクタラベルの情報が受け取れない場合、このセレクタラベルを適用したトラックが再生されます。
![A08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/44e2ce61-eff0-2beb-c0fb-b493ae9f16c7.png)
同じ用に材質名のセレクタラベルを作っていきます。
![A09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8e1ece8c-f932-a1ec-f376-05f47a04578a.png)
使う予定の材質名を持つセレクタラベルをすべて作成します。
![A10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8b4499f3-5d19-08e2-9eda-54758ccaefce.png)
キューを選択し、インスペクター上でセレクタ名を設定します。
![A11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ebdce888-e20f-aeff-603c-c2fa72236642.png)
すべてのトラックに対して、セレクタラベルを設定します。
![A12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/91c2c5ed-5c57-9bda-afc0-e2958d230ac5.png)
![A13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c681e26c-16e7-3bdb-4b9d-2056fd6bc4a0.png)


###セッションウィンドウでのテスト再生
セレクタラベルを使ったキューをテスト再生するには、セッションウィンドウを使います。
ツールバーの「表示」→「セッションウィンドウ」から呼び出します。
![A25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c57bb249-51ba-2c2a-f6b3-7ade950941b8.png)
![A26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a69a5248-b80b-7241-d985-1642169c4830.png)
ワークユニットツリーから、セッションウィンドウの下段に試聴したいキューをドラッグアンドドロップします。
![A27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f1308bd6-31be-6c31-7b89-be41ff3a20f2.png)
「セレクタ」のボタンを押すと、設定したセレクタラベルを試せる機能が呼び出せます。
![A28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ca1b235a-6025-6a48-525f-0d422e191875.png)
すべてのセレクタラベルを順に聞いて試してみてください。
![A29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a79c9cdf-d57d-1a6f-3c1e-e6f18de286af.png)


###インスペクターでの設定
音が鳴るたびにピッチや発声角度に少しだけランダム性をもたせます。
トラックを選択し、インスペクター上でピッチとパンニング（角度）の設定をします。
![A16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/fc15a883-af01-4e37-17e3-1aaeb69ef449.png)
![A17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/17b32b8b-7df5-870a-0938-561135cd294f.png)



###AISACコントロールで音にエフェクトをかける
材質のパラメータにより音に変化をつけるため、AISACコントロールを作成します。音のこもり具合をつけたいので、今回は「バンドパス」と「エンベロープ」についてAISACを作ります。
トラックリストの空欄で右クリックし、「新規オブジェクト」→「AISACの作成」をクリックします。
![A20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/3c8e1afb-7a43-92dc-e417-bccb73230b54.png)
まずは**バンドパス - Cof高域**のAISACを作成します。
![A21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1f357c70-bad9-5a6c-d6c4-47f8022d37a5.png)
右に行くにつれ数値が下がるグラフを作ります。途中までは音をよく響かせるため、値が1の状態をキープしてください。
上部のスライダーを動かして音をチェックしながら作るといいかもしれません。
![A22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f3467708-263b-6e36-26ba-a0e707ab41a9.png)
次に**エンベロープ - アタック時間**のAISACを作成します。
![A23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/4202ef47-405e-d671-a546-1124a8614f70.png)
今度は図のように右に行くにつれ上がるグラフを、正し最大値は低めにしておきます。アタック時間を上げると再生開始時の音量が絞られるため、あまり度合いを上げると音が聞こえなくなってしまうためです。
途中までは値を0にして、全体的なグラフを緩やかに作ると良さそうです。
![A24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/6728b106-ceb1-f2f2-d722-826730e09c03.png)


###キューシートのビルド
すべて完成したら、キューシートをビルドしてUE4に持っていきます。
![A19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ae9097d7-a23b-c47c-ed9b-c6c9a5dc5d8b.png)


##UE4での実装

###キューシートのインポート
ビルドしたacb、acfファイルをインポートします。
![B01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/376c93a7-e45d-00a8-c8bf-d7bcb6923f4e.png)
「Project Settings」→「CriWare」のタブにて、Atom Configファイルが今回使用するものになっているかを確認してください。
![B02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/05a82b47-7fd9-5736-76f9-c18007723ef9.png)
UE4側で3D空間における音の減衰などを設定する場合、Atom Cueを開き、「Default Attenuation」にSound Attenuationファイルを適用してください。
![B27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b81675e6-781c-c232-993f-905c8c397b6b.png)



###Physical Surfaceの登録
物体に具体的な材質カテゴリをつけて管理したい場合、Physical Surfaceを使います。
「Project Settings」→「Physics」タブに移動し、下にスクロールすると「Physical Surface」の項目があります。
![B03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b9ad25d8-5aa0-17a9-8981-0e2c0c4816e1.png)
初期状態ではDefaultのみ入力されていますので、AtomCraftでセレクタラベルに設定した材質名をここに入力していきましょう。
![B04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/910d2af8-758e-21c2-d825-b56e191b56fe.png)
ここを編集しても、のちの作業にすぐに反映されない場合がありますので、一度UE4のエディタを再起動します。


###Physical Materialの作成・設定
物体の材質パラメータを設定する「Physical Material」を作っていきます。
コンテンツブラウザの適当なフォルダで右クリックし、「Physics」→「Physical Material」を選択します。
![B05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c67f9ebf-4266-390f-db83-1195a8bc219a.png)
「Physical Material」を選択して「Select」ボタンを押します。
![B06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/287354cf-951e-59a7-28be-7a80f4ec3dba.png)
Physical Materialが作成されました。適当な名前をつけます。
![B07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/6f5ab6f9-f7e8-6050-bb76-e13ad9c7fdca.png)

ダブルクリックして開くと、材質の摩擦や反発力、密度を設定できるウィンドウが開きます。
「Friction」が摩擦、「Restitution」が反発力です。
![B08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0c3c6439-5875-f67d-c6a0-e6e0c06fe13a.png)
雑な設定ですが、変化をテストするため下の画像のような数値にしてみましょう。
摩擦は0、反発力は1.0で、バウンドした物体は100%の力を保って跳ねます。非現実的ですね。
![B09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d8a40d93-0944-3b6b-4f2a-45e5a95d729a.png)


###物体用アクターの作成
衝突させる物体となるアクターを作ります。
![B10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/2ccf116e-7986-6710-691d-d69d52f92972.png)
親クラスは「Actor」です。
![B16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/5e138c14-05fa-5e7b-c559-edabb666199a.png)
作成したらダブルクリックして開きます。
まずは「+Add Component」ボタンを押して「Cube」を追加します。
![B11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/6c9827ea-ab1d-d489-6efd-ad8ff5291b79.png)
Cubeコンポーネントを選択し、Detailsパネルにて「Simulate Physics」にチェックを入れます。
![B12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d51213b1-5621-ab61-134f-fb9812cf3176.png)
また、「Phys Material Override」に先ほど作成したPhysical Materialを入れます。
![B13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ab8d86be-7348-0fdb-3ddc-1e8221dedc61.png)
サウンドを発生させるためのコンポーネントも作成します。
「Atom Component」を追加します。
![B14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/865a5f06-3d1c-f094-9d50-f79067c1bb6e.png)
Atomコンポーネントを選択し、DetailsパネルにてAtomCraftで作成したAtomキューを設定します。
![B15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e25a6359-5586-0378-4673-6524187d10ee.png)


##ブループリント編集

アクターのイベントグラフに移り、処理を書いていきます。
ここからの処理は、以下の記事の発展編になっていますので詳しい解説、ノードの配置方法などはこちらを参照してください。
**ADX2+UE4で、物理挙動にランダム性のある効果音をつける**
https://qiita.com/SigRem/items/77644c292a1f3e1e16fd

###基本的なサウンドの発生
処理開始時に、**Set Notify Rigid Body Collision**で物体衝突時の通知を有効にします。
![B17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/02cf523e-768f-8379-50a4-09f07cee40cf.png)
衝突時に衝撃の強さが一定以上の場合、Atomコンポーネントを再生します。その際、ボリュームも衝撃の強さに合わせて増減させます。
![B18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/554c6776-d42c-95e7-ba6b-992d6778d248.png)

ここまででいったんアクターをレベルに配置して再生してみると、すさまじい速さでキューブが跳ね回る様子が楽しめます。ぶつかった際の音が鳴っていれば大丈夫です。
![B30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d23d4917-9e3c-29a3-f62e-3dde2e438935.png)


###材質の種類に応じて音を変える
物体に材質を設定し、セレクタラベルを使用し対応した音を出してみる処理を加えてみます。
キューブに適用したPhysical Materialを開きます。
「Surface Type」の欄に任意の材質を設定します。ここには「Project Settings」→「Physics」で入力した材質名が反映されます。
![B19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/73574f1b-8465-567c-c06b-f3c46a95cd40.png)

ブループリントエディタに戻ります。
衝突した物体のPhysical Materialは下の画像のように、**Break Hit Result**の「Phys Mat」から取得することができます。
![B20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/4a6f6184-78b5-ca00-944b-6075b4db7a39.png)
さらに**Get Surface Type**ノードをつなげば、衝突面のSurface Type名を取得できます。
![B21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8c6f065c-0ce5-5df8-1732-a9ad0eeb00f3.png)
Surface Typeごとに異なる音を鳴らしたいので、項目ごとに分岐できる**Switch**ノードを使います。
**Get Surface Type**ノードから線を伸ばし、「switch」と検索して**Switch on EPhysicalSurface**ノードを配置します。
![B22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c7f3fdbd-1ec2-3eb5-3cd0-dc0c196d066e.png)
![B23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/3bbc44da-095f-ddb0-c910-ecf862288b84.png)
設定したPhysical Surfaceすべての分岐が可能になるので、**Set Selector Label**でAtom Cueに対してセレクタラベルを与え、該当のトラックを再生するようにします。
![B24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f367b437-328e-ded0-8807-aa745497d6bc.png)
すべて分岐すると以下の画像のようになります。ちょっとグラフが嵩みますが……。
![B25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0017d8d0-7722-cace-9156-61a6e34a1df3.png)


###摩擦、反発力の度合いにより音を変化させる
衝突した物体の摩擦を得るには**Break Hit Result**の「Phys Mat」から**Get Friction**ノードを、反発力を得るには**Get Restitution**ノードを引き出します。
![B26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f4078444-fc20-c2ac-9c64-294487cf2135.png)
**Play**ノードなどのあとに、**Set Aisac by Name**で摩擦情報をAISACコントロールとしてAtom Cueに渡してあげます。
![B28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1364e6cb-bc1e-bd93-d0cb-9f0b00681de0.png)
これにより、摩擦が大きくなると音がくぐもり、鈍い音に変わります。
反発力に対しても同様なのですが、こちらは反発力が高くなるほどはっきりとした音になるのが理想です。
そのため、下の画像のように「1-反発力」の式を作り、解が1に近づくほど「エンベロープ - アタック時間」の効果が少なくなるようにします。
![B29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c25d5eea-4810-cde6-3719-e09333d50374.png)

この状態でPhysical Materialの数値をテストプレイしてみると、物体の挙動が変わるに連れ音も同じように変わっていきます。