UE4+ADXで実装するUIサウンド（基礎、UIアニメーション編）

# はじめに
アンリアルエンジン4とサウンドミドルウェア「ADX for UE4」を使い、UI（UMG）に連動してサウンドを再生する実装例です。
この記事ではUIアニメーションにAtom Cueを組み込み、操作に反応する処理を作ります。
また、状態によって音を変化させ、たとえば「現在UIが操作可or不可かといった状態に応じてサウンドを分岐させる」といったことも可能です。


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

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

記事執筆時点のADX for UE4のSDKバージョンはv1_29です。

# 前提
ADX2 for UE4の導入や基本的な使い方は以下の記事にあります。必要に応じて参照してください。
ADX2 for UE4の導入で、一歩上のサウンド表現を（導入編）
https://qiita.com/SigRem/items/4250925f6d66a4fd287a
ADX2 for UE4の導入で、一歩上のサウンド表現を（実践編）
https://qiita.com/SigRem/items/c089b71c42e898980a46


# 実装

## UIを作成する

UI作成にはUEのUIデザイン機能である「UMG」（Unreal Motion Graphics）を使用します。
まずは新規にウィジェットを作成します。
コンテンツブラウザの任意の階層で右クリックし、「User Interface」→「Widget Blueprint」を選択します。
![A01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/10811a44-adc9-0f2b-042a-15970c5f0c6b.png)
適当な名前をつけてダブルクリックします。
![A02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b0928759-e8a3-b5b7-4021-4592b6913ce4.png)

UMGのエディタが開きます。
![A03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/df1f1743-6aa1-fae1-48ca-77e13a561f0d.png)
適当にイメージとテキストを配置し、ウィンドウ（に見えるもの）を作ります。
![A04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/696802d2-4796-e9e7-5dcb-62e67d3dda6d.png)

## UIアニメーションを作成し、サウンドを組み込む

左下の「Animations」パネルの「+Animation」ボタンで新規にUIアニメーションを追加します。
![A05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/600cb89f-fcf4-53cf-940c-8fde65767476.png)
分かりやすい名前をつけます。あとでブループリントから呼び出すので、判別しやすいものにしておきましょう。
![A06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/dbb83606-1160-34eb-a9f9-acc4ca8043fd.png)
キーを打ち、UIがフェードインして現れる、単純なアニメーションを作りました。
![A07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d557589c-ac68-14c5-5ebb-b471958a47df.png)
Timelineパネルの「+Track」ボタンから、Atom Trackが追加できます。名前のとおり、Atom Cueを再生することができるトラックです。
![A08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/80d7a39c-5916-6b20-951e-b82da186096b.png)
タイムライン上に任意のAtom Cueが登録でき、自由に配置できます。
![A09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8dc1e6e1-a6e3-7455-a980-82d4d294cabf.png)
Atom Cueを配置しました。
![A10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/91f49665-6a74-9fad-8665-46e9d37449e3.png)
UIアニメーションに配置したAtom Cueですが、**セレクタやコンボ、ランダムなどのAtomCraftでデザインしたサウンド機能が反映される**のが便利です。
画像内の例にあげた「Cue_A_Piano」は再生されるたびにランダムな音階のピアノの音を再生するキューであり、UIアニメーションが再生される（ウィンドウが現れる）たびに異なる音が再生されることになります。


## UIアニメーションを呼び出す

アニメーションは完成しましたが、再生するための処理を作っていないのでゲーム中では呼び出されません。
UMGエディタ右上の「Graph」をクリックしてイベントグラフに移動します。
![A11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b0ea249e-e367-3af6-9217-dee399430e00.png)
「My Blueprint」パネルから、変数と同じようにアニメーションの**Get**ノードが置けます。
![A12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0a92bbb1-3e2b-439e-0c66-69c2c99a74c5.png)
アニメーションのGetノードから線を引き出し、**Play Animation**ノードを配置します。
UIが呼び出されるとまず**Event Construct**が発火するので、そこにつなげます。
![A13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9cc15eee-cbfa-48a6-73f7-936204d12c5c.png)

レベルブループリントに移動し、UI本体を呼び出す処理を書いていきます。
![A14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/28ed7cd3-e8c6-4c8e-0220-fb074eadc066.png)
UIを**Create Widget**ノードで作成し、**Add to Viewport**で画面に表示させます。
![A15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/23833882-b020-192c-75ca-6817db9a9273.png)
「R」キーを一度押したらUIを呼び出し、もう一度押すと画面から削除する処理はこのようになります。
![A16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/cfc4d4eb-793b-9120-e911-c674136d2646.png)
ここで一度テストしてみましょう。たしかに処理どおりに動きますが、UIが消える瞬間があっけないので、クローズするためのアニメーションを用意したほうが良さそうです。

## UIクローズ時のアニメーション

クローズ用アニメーションはUI呼び出し時のアニメーションを逆再生してもいいのですが、今のところブループリントから逆再生するとAtom Cueは再生されないようです。
![A22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ec524996-89ea-23ee-0e2b-c9dbe36035e0.png)
そのため、新しくUIクローズ用アニメーションを作ってしまいましょう。

UMGのデザイナー画面に戻り、アニメーションを右クリックし「Duplicate」で複製します。
![A17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0e6ddabe-ef89-0fde-4641-ad3bb466259f.png)
キーのタイミングや数値を調節し、出現時とは逆の動きをさせます。さらに、再生するサウンドをUIクローズ用のAtom Cueに差し替えます。
![A18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ee6f0872-9327-e9ef-951a-3566ab4912ef.png)
**UMGのイベントグラフ**で、新規にカスタムイベントを作成します。
名前は「CloseWidget」とし、外部からUIのクローズ処理が呼び出せるようにします。
処理内容は呼び出し時と同じく、クローズ用のアニメーションを再生するだけです。
![A19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1cac6e18-9075-28ab-5d70-16150e98ed7f.png)
アニメーションを再生するだけだと内部的にはUIが動き続けていることになるので、アニメーションの再生が終わったら画面上から削除する処理も必要です。
**Event On Animation Finished**はアニメーション再生終了時に自動的に呼び出されるイベントです。「Animation」アウトプットピンから再生終了したアニメーションが取得できるので、それがクローズ用のアニメーションと同一であれば**Remove from Parent**でUIを削除します。
![A20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c5315a91-07bd-b3ef-e14c-e7c2edef2d71.png)
**レベルブループリント**側も処理を変える必要があります。カスタムイベント**CloseWidget**をUIから呼び出し、クローズ処理を開始させます。
![A21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/27935be8-a035-0a67-bafa-0d5b0ade234c.png)

これでスムーズにUIが表示・削除されるようになりました。それぞれ異なるサウンドも再生されています。


## 状況に応じてサウンドを分岐させる

特に重要なメッセージを表示させる場合など、アニメーションから再生するサウンドを変更したい場合もあります。
タイムライン上のAtom Cueを右クリックし、「Properties」から「Selector Labels」の項でセレクターによるサウンド変化が可能です。
![B01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b3e538c6-6098-3145-c894-69ceee003cc9.png)
任意のセレクタとセレクタラベルを指定できます。
![B02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/325f2039-b423-2089-852f-51ea4d4cbffd.png)

UIごとに決め打ちでセレクタラベルを指定したい場合はこれで完了ですが、ブループリントから動的にセレクターラベルを設定することもできます。
**Set Global Label to Selector by Name**ノードはすべてのキューに影響するため、**UI内で再生されるAtom Cueにも有効**です。
![B03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/db20a9c6-ceb6-179b-76e0-3b26dc3d1a5e.png)
その場合でも、アニメーション内のセレクターラベル指定が優先されるため削除しておく必要があります。UIの用途によって使い分けましょう。
![B04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0c3f83f2-105e-7197-133f-cc7a3ad4f0b5.png)

また、UI専用のセレクターフォルダを作っておけば他のゲーム内サウンドに影響する心配がなくなります。


## 補足

UIで再生したAtom Cueが3Dサウンドだったり、減衰設定が含まれていると（おそらく）原点からサウンドが聞こえてしまうので、2Dサウンドとしてデザインするのがおすすめです。