UE4+ADX2でつくる、BGMとシンクロした演出

# はじめに
アンリアルエンジン4とサウンドミドルウェア「ADX2 for UE4」を連携させ、BGMの任意のタイミングで演出をしてみます。

アップデートされたADX2LEの新機能である「シーケンスコールバックマーカー」を使用してBGMにタイミング情報を埋め込み、UE4のブループリントからイベントを起動する手法です。


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

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

# 実装

## AtomCraftでBGMにタイミング情報を設定する

まずはAtomCraftで、BGMにイベントの発火タイミングを設定していきます。

### キューの作成
キューを新規に作成します。
![A01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/64b359cc-07bb-8233-65f2-98383b186d03.png)
任意のBGMをインポートし、キュー内にドラッグアンドドロップします。
![A02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8e9ef092-aec2-6fa9-138c-327d8427ff90.png)

### ビート同期情報の作成
トラックリストの空欄で右クリックし、「ビート同期情報の作成」を選択します。
![A03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ad75121b-6a07-deeb-d51d-1fe0978822cf.png)
トラック上に「BeatSync」という表示が出現します。
クリックして、インスペクターにてBPMを入力します。
![A04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9eb56dfc-1f12-0e2b-a82f-83912d4e9186.png)
もし曲のBPMが不明な場合、マテリアルツリーのwavファイルを右クリックし、「BPM解析」で取得することが可能です。
![A05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1fffd5c6-4820-df11-d44f-cf7e21f724dc.png)
解析した情報はログに出力されます。
![A06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/bfe67b7b-9b83-4316-9d8a-1ecfe14060eb.png)

### コールバックマーカーの埋め込み
トラックリストで右クリックし、「マーカーの作成」を選択します。
![A07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8758dec2-ea2b-5ec4-8366-259b628a39b2.png)
マーカーの設定ウィンドウが出るので、タイプを「コールバック」に変更します。名前やタグを適当に入力しておき、「追加」ボタンを押します。
今回は曲を「Verse」、「Bridge」、「Chorus」（広義のAメロ、Bメロ、サビに当たります）という要素に分けてイベントを埋め込んでみます。
まずは「Callback_Verse」を作ります。
![A08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/216c508a-02c0-963d-81bb-29302a841d77.png)
「Cb」というマーカーが出現するので、Aメロの開始場所まで移動させます。
![A09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/2c38268e-7d63-6ac8-e5ee-d8c65a360e55.png)
同じようにして、「Bridge」「Chorus」のコールバックマーカーを作り、任意のタイミングにマーカーを埋め込みます。
![A10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9532f567-f429-8e4b-14f8-f70a4367b072.png)
![A11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e1590b76-1703-5a8e-88ca-593ba8eb1d81.png)
![A12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d3b5dfb3-ae35-1d04-49d5-269b5c0978c5.png)
コールバック設定の「ID」は被らないものを用意しておくと後々便利です。


### キューシートのビルド
ここまで完了したらキューシートをビルドします。
![A13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1a8deac6-556f-9b79-bfbc-0ff212ded69e.png)
![A14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e2b10551-9ef3-040b-3fcb-087e1df41338.png)

## ブループリントからイベントを起動する
### キューシートのインポート
ビルドしたキューシートをインポートします。acbファイル、acfファイルをドラッグアンドドロップコンテンツブラウザにドラッグアンドドロップします。
![B01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f7449287-b97e-6fb3-b3b6-add9f95b1f43.png)
ツールバーの「Edit」→「Project Settings」を開き、
![B02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c5ea8603-ad90-55cd-deb2-d703c9378e61.png)
「CriWare」のタブで、「Atom Config」に出力したacfファイルを指定しておきます。
![B03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/72cd5b01-f06e-83b1-0b5f-5fad107a97fd.png)


### キューをレベルに配置する
BGMとなるキューをレベル上に配置しました。ゲームを再生すると、BGMも流れ出すはずです。
![B04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/401b16a6-0cce-85fb-4ebe-30081826b917.png)

### ブループリントでイベントを呼び出す
配置したキューをレベル上で選択しておき……
![B05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/71f3da3b-49d8-abbd-be2a-6abbd1d6028c.png)
「Blueprints」→「Open Level Blueprint」からレベルブループリントを開きます。
![B06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/74b37ff7-f688-46ca-2075-62cbb4bced38.png)
空欄にて「Create a Reference to （キュー名）」を選択すると、キューのリファレンスノードが配置されます。
![B07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/67fc27d8-c6ba-51f5-f97e-8c613935f72d.png)
![B08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ea8ac7cf-873f-6c93-2be0-5ef8cd7d45aa.png)

リファレンスノードから線を引き出し、**Get Atom Component**を配置します。
![B09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/3094100e-0590-d34a-f800-fdd0c036f2cb.png)
さらに線を伸ばし、**Bind Event to On Atom Sequence Callback**を作成します。
似た名前のノードが複数あるのでご注意を。
![B10A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/65361628-0f5b-6a1a-1d40-df352ecf81ee.png)
![B10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/78d2a527-5d19-0fa4-edd7-f0a82ae03046.png)
「Event」ピンから線を伸ばし、**Add Custom Event**でカスタムイベントを作成します。
![B11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9752cac5-82ae-2d2c-eaaf-fe704cc2eacf.png)
コールバックタイミングで呼び出されるイベントなので、今回は「OnCallBack」と名前をつけました。
![B12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1693fc38-453e-529a-5023-2ffa9917ea88.png)
![B13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b797e67d-719b-431f-344b-b6269e69470d.png)
これで、何らかのシーケンスコールバックが埋め込まれたタイミングでイベントが発火します。


### 任意の演出を作る

コールバックの名前やタグによって処理を分岐させ、AメロやBメロ、サビのタイミングで違う演出が呼び出せるようにしていきます。
「Sequence Info」から引き出した**Break**ノードで、シーケンスコールバックの情報を取得することが可能です。
![B14A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c69288ea-209d-f512-1bdd-a62fef29d73a.png)
![B14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/45464d4e-550c-cb37-86eb-4a0c386534a1.png)
「Tag Name」や「CallBack ID」から線を引き出し、各**Switch**ノードで処理を簡単に分岐させられます。
![B15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0aa8cbb1-000d-5db7-eff5-7bbfa695f685.png)
![B16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b41d397f-4e21-5a14-14e7-6441d2f69488.png)

**Switch**ノードでコールバック名ごとに処理を書いていけば、コールバックマーカーが増えても異なる演出を実装することができます。