ゲームの状況に合わせて効果音にバリエーションを by ADX2 for UE4

# はじめに
アンリアルエンジン4と、サウンドミドルウェア「ADX2 for UE4」を連携させ、
同じ現象でもゲームの状況に応じて異なる効果音が再生されるようにします。
UE4.23+「ADX2 LE v2.10.05」を使用します。

AtomCraftで使用できる「セレクタ」を使い、ひとつのサウンドデータに様々な音を内包します。
![I01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/41b0dcbd-c83d-3f47-8de6-5120b1e8f5bb.png)
2段ジャンプできるキャラクターが、地上でジャンプしたのか、空中でジャンプしたのかによって音を分岐させています。
2種類の音が鳴りますが、アセット上のファイルはひとつにまとまっています。

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


#やること
- AtomCraftで複数のサウンドを持つスイッチキューを作成
- UE4にインポート
- ブループリントでアクションによるラベルの分岐
- テストプレイ


# 実装

##AtomCraftで複数のサウンドを持つキューを作成

### 素材を用意
AtomCraftのマテリアルツリーにサウンド素材をインポートします。
![A01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/98a7d21a-6a79-a85a-72ff-5c44ed362d25.png)
サンプルとして、地上用のジャンプ用に「NormalJump」、空中ジャンプ用に「SpecialJump」をインポートしています。

### キューの作成
Atom Cueを作成します。
作成時には「スイッチ」を選びます。
![A02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/4789b90c-5118-e141-0f8d-8cfb8ab7755b.png)
このタイプのAtom Cueは、「セレクタ」及び「セレクタラベル」という値をゲーム中に受け取り、それに応じたトラックを再生するものです。
![I03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e0d7d7d8-6f1c-8170-bb7d-f2c959fbb2eb.png)

2種類以上のサウンドを用意し、それぞれ違うトラックに入れます。
![A03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/087692c5-b5e1-24bf-f91f-a1a5c6dc5b9a.png)
上のトラックは地上でジャンプしたときの、下のトラックは空中でジャンプしたときの音になります。
分かりやすいようにトラックをリネームします。
![A04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/42bf5daf-e759-0364-8fca-ec410e59b010.png)


### セレクターラベルの設定
必要に応じたトラックを再生するため、セレクター及びセレクターラベルを作成します。
プロジェクトツリーの「セレクタフォルダ」を右クリックし、「新規オブジェクト」→「セレクタの作成」を選びます。
![A05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/446db7c7-7fab-adee-5ce4-5723143485f6.png)
作成したセレクタをリネームし、分かりやすいものに変えます。ここでは「Action」としました。
![A06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/16252e04-adbe-d171-7b21-6f1a259266bb.png)

さらにセレクタを右クリックし、「新規オブジェクト」→「セレクタラベル」でラベルを作ります。
![A07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/332973cc-3d88-fde9-1b0a-a8e0329b9dc7.png)
セレクタラベルの名前を設定するウィンドウが開くので、適当な名前をつけます。
![A08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/79d057b8-a6f3-1f43-8fe0-daad326d0cf8.png)
2つのセレクタラベルを作り、それぞれ「Action_Ground」「Action_Air」としました。
![A09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/7c5c811b-59d9-13ab-5a73-224334b3b190.png)

これでセレクター「Action」内に「Action_Ground」「Action_Air」というセレクタラベルが用意されました。
ゲームの実行中、地上ならば「Action_Ground」を、空中なら「Action_Air」のラベルを渡し、違った音を再生させます。

### キュー側の設定
準備したセレクターをキューに設定します。
「ワークユニットツリー」にて、**スイッチタイプのキューが選択**されていることを確認します。
![A10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/93fd059c-9a83-a8fb-c737-903733070f26.png)
インスペクタ下部の「スイッチ」をクリックします。
![A11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/704178d7-5d4c-a115-4ae5-04e3ffccda49.png)
「スイッチ変数」から先ほど設定したセレクタが参照できるので、セレクタフォルダ「Action」を選びます。
![A12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/7da12dc8-5ae8-b4c1-c632-80206cb80aa0.png)
セレクタフォルダ下のセレクタラベルも表示されます。
![A13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/49cf33a5-9032-5fb5-d608-98da7c1631aa.png)
対応したトラックに、任意のセレクタラベルを設定します。
![A14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/7f4577f7-58a0-5657-c28d-d3f54fb55b27.png)


###キューシートのエクスポート
通常通り、キューシートをエクスポートします。
![A15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e2d26afd-9e55-b11d-06d2-36f16eb297f7.png)
![A16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/3f48cd94-28d6-b856-1f6b-bcf164a432a6.png)

これでAtomCraft側の作業は完了です。


##UE4での実装

### キューシートをインポート
AtomCraftからエクスポートしたファイルをインポートします。
![B01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/540ec4cb-f528-7cb6-10f8-0eb5755cfa81.png)
プロジェクト設定を開き、「CriWare」タブから～～に新しいAtom Configファイルを設定するのをお忘れなく。
![B02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/45f0ea50-2a97-9444-f08f-060a75edb2e4.png)


### キャラクターの空中ジャンプを可能にする
UE4デフォルトのキャラクターが空中ジャンプ可能になるよう変更します。
「Content」→「ThirdPersonCPP」→「Blueprints」にある「ThirdPersonCharacter」を開きます。
![B06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/47b5f6b6-b168-3030-15c9-b08c642e749b.png)
コンポーネントリストから「ThirdPersonCharacter(Self)」を選択します。
![B07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/04a2c071-a575-42d3-7ccc-a7da894b4acf.png)
Detailsパネルで「jump」を検索し、「JumpMaxCount」に「2」を入力。
![B08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8e6b5562-8937-aab9-bd2c-ecd33e09bf4b.png)


### キャラクターのジャンプ処理を書き換える
EventGraphを開き、「Input Jump」のイベントノードから処理を書きます。これはキャラクターにデフォルトでついているジャンプ処理を書き換えます。
ノード全体の完成図がこちら！（下で順番に解説します）
![B09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e6df3e09-5f06-0ac7-0861-93ac9bddb178.png)

#### ジャンプ回数が残っているか判断
![B10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/702735f4-cea6-5863-6ef9-437e93838dc0.png)
キャラクタークラスにデフォルトで用意されている変数「JumpCurrentCount」（現在のジャンプ回数）と「JumpMaxCount」（最大ジャンプ数）を比較し、ジャンプ可能な状況かBranchノードで判断します。

#### セレクタラベルを指定
![B11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b6a7acfe-2f0d-da64-5461-8b8f7e216b74.png)
「Sequence」ノードでこの後の処理を整理します。
「CharacterComponent」コンポーネントをGetし、そこから「isFalling」ノードでキャラクターが空中にいるか判断できます。
![B13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a2d87e67-5b06-58e5-35e6-44ce5d281a46.png)
![B14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/22332dc4-4a31-6874-7cc5-d35e40d5815b.png)

「Set Global Label to Selector by Name」ノードで、True（空中）側には「Action_Air」を、False（地上）側には「Action_Ground」のセレクタラベルを指定します。SelectorNameにはセレクタフォルダ名である「Action」を入力しておきます。
これでAtomCraftで作成したトラックの分岐が可能になります。「Set Global Label to Selector by Name」は再生されるすべてのAtom Cueに対してセレクタラベルを上書きしますが、個別に変更したい場合は「Set Selector Label」ノードを使用します。
こちらはAtom Componentを対象に指定します。
![B15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/3a24b0af-10e8-5dbe-66d7-8d86660cad02.png)

#### サウンドを再生し、ジャンプを実行
![B12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1629e0d9-46d6-86a4-bfe5-37668ee4ed7b.png)
「Play Sound Attached」ノードでサウンドを再生します。UE4デフォルトの再生ノードではなく、ADX2 for UE4で用意された「Play Sound Attached」ノードを使います。
「Jump」ノードでジャンプを実行します。

これですべての実装が完成しました！
セレクタフォルダは複数のキューで共有できるので、ジャンプだけでなく他のアクションについても地上用、空中用といったサウンド分岐ができるでしょう。
他にも足元の材質に応じて足音を変える、といった使い方もできます。


## テストプレイ
Spaceキーでマネキンがジャンプします。「JumpMaxCount」を増やしたので、空中でも一度だけ追加のジャンプが可能です。
その際、通常のジャンプと空中ジャンプでは効果音が異なっているはずです。
空中でジャンプを連打しても追加のジャンプは一度だけになっていること、効果音が連続で再生されないことを確認してください。
もしうまくいっていない場合、ブループリントノードの構成を見直してみましょう。


## アニメーションにAtomSound再生タイミングを設定する場合
今回はジャンプ入力時にサウンドを再生しましたが、キャラクターのアニメーションに効果音の再生を組み込むこともできます。
デフォルトキャラクターのマネキンの場合、「Content」→「Mannequin」→「Animations」にある「ThirdPersonJump_Start」を開きます。
![B03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ba7d5e96-ec2c-ba5b-c323-e9a87d5967a8.png)
タイムラインの「Notifies」の適当な位置をクリックし、「Add Notify」→「PlayAtomCue」をクリックします。
![B04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0f341046-eed1-4af4-d779-f40222b9a789.png)
Atom Soundの再生が組み込まれるので、Detailsパネルにて再生するサウンドを指定します。
![B05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/6c2ddea1-13c6-49f7-2153-eeccb7b920e6.png)

UE4デフォルトのマネキンは空中ジャンプ時に「ThirdPersonJump_Start」が再度再生される仕組みではないため、今回の記事ではこの方法を取りませんでした。