UE5+サウンドミドルウェアADXで、BGMに動的なドラムパートを（発展編）

# はじめに
アンリアルエンジンとサウンドミドルウェア「ADX for UE」を連携させ、パーカッションのないメロディラインに動的にドラムパートを追加し、さらにランタイムでドラムパターンを変化させていけるシステムの実装チュートリアルです。

https://twitter.com/sleepyslowsheep/status/1605430553586458627?s=20&t=zOqb5VhKJcewl5Ke7lz6-A

ゲーム内のシチュエーションに合わせてパートを追加するだけでなく、細かな状況に合わせて使用する打楽器を変えてみたり、はたまたユーザーがドラムパターンを作れてしまう、といった活用も可能です。

当記事は「UE5+サウンドミドルウェアADXで、BGMに動的なドラムパートを（再生編）」の発展編として書かれています。
まずは次の記事で、基本的な実装を試してみてください。

https://qiita.com/SigRem/private/de6eace90d0a433d916a


# 前提

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

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

記事執筆時点のADX for UEのSDKバージョンはADX LE UE SDK(1.31.00.01)です。

ADX for UEの導入や基本的な使い方は以下の記事にあります。必要に応じて参照してください。
**ADX for UEの導入で、一歩上のサウンド表現を（導入編）**

https://qiita.com/SigRem/items/4250925f6d66a4fd287a

**ADX for UEの導入で、一歩上のサウンド表現を（実践編）**

https://qiita.com/SigRem/items/c089b71c42e898980a46


# 実装

## AtomCraftでBeatSyncタイミングを細かくする

再生編で構成したキューでは、1小節にコールバックイベントが4回実行されます。UEで処理を加え1小節につき8回の実行になりましたが、ドラムパターンを構成するなら16分割ほど欲しいところです。

AtomCraftに戻り、BeatSyncのタイミングを変えてみましょう。


### BeatSyncの設定変更

まずはメロディのキュー内にある「BeatSync」マーカーを選択します。
![A01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b32f6199-92f8-9e1f-d86b-13fb653a95da.png)
正攻法ではなさそうですが、**bpmを4倍、分子を16に**することで1小節を16分割します。
![A02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/bc62d892-8ce0-cdfd-02b1-84ca801fcb10.png)
本来のbpmが124の場合、4倍して「496」を入力します。

すべてのメロディキューに対して同様の手順を踏みます。

### キューシートのビルド

通常と同じ手順でキューシートをビルドします。


## UEで動的なドラムパターンを構成する

ここから再びUEでの作業に移ります。

### キューシートのインポート

キューシートを再インポートします。
すべてのキューがコンテンツブラウザにあることを確認しておいてください。
![B01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f1583825-d44a-aea5-1c4c-4d444315e44f.png)


### BeatSyncの動作確認

一度そのまま実行して動作を見てみましょう。
より細かいタイミングで、慌ただしくドラムが鳴るようになったはずです。


### ドラムパターン用変数を読み取り、再生する

再生編で使ったブループリントアクターを開きます。
作成した一連の処理ですが、次の画像で選択している部分を一度消してしまいましょう。
![B02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/90ae21fb-ab99-9973-0700-6cdfb5dcdf2b.png)
新しく処理を書いていきます。
![B03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/22ae3b60-3973-b4e9-ecdd-88db3ca4616e.png)
MyBlueprintパネルにて、新しくBool型の変数を追加します。
![B04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/689e43ec-4486-17ef-013b-d8c92783cb66.png)
これはドラムパターンを記憶しておくための変数です。1小節につき16回ぶんのパターンを記憶したいので、配列（Array）変数に変更します。
Detailsパネルにて、「Single」から「**Array**」に設定します。
これでひとつの変数にいくつもの値を持つことができます。
![B05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/dc84d1da-3e15-4c73-fb39-3dee61967d16.png)
**一度コンパイル**し、初期値を設定します。
Detailsパネルの「Default Value」にて、+（Add Element）ボタンを押し最大が「Index 16」になるまで追加します。
本来なら要素は16個（Index 15まで）あればいいのですが、DAWなどのツールではパターンの表記が1～16までとなっていることが多いためそれに合わせています。
（変数は0からカウントされるので、後でオフセットを計算する必要があります）
**ややこしいと感じたらとりあえず画像を真似して設定してみてください。**
![B06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b236a2c7-df63-c3d0-f98a-453c2e27e353.png)
基本のキックパターンとして次の画像のようにチェックをつけてみましょう。
![B07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/5344d8e8-b249-4673-87a7-5690767bf29c.png)
ドラムパターンを実際に再生する処理を書きます。
変数「Pattern_Kick」を**Get**し、そこから線を伸ばし**Get(a copy)** ノードを配置します。
![B08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/2b52883b-f0a7-5236-b204-76a8c3d282a1.png)
配列変数のGetノードはインデックス番号をInt型で指定してあげる必要があります。
先ほどDAWの表記に合わせるためにインデックス番号を余分に追加したので、そのぶんを加算してつなげます。
![B09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ce339e66-c38a-54d5-8507-7ae613d1a8aa.png)
**Branch**で現在の再生位置のドラム再生が有効かドラムパターン上で照合し、Trueであれば**Spawn Atom Sound 2D**でキック音を再生します。
![B10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/75508850-0818-6545-a31d-1d1d3103fb58.png)

ここで試しにゲームを再生してみましょう。チェックをつけた場所でのみキック音が鳴るはずです。

レベル上でパターンをカスタムできるよう、変数の目玉アイコンをクリックして公開しておきましょう。
![B11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/50ba72e8-1fc6-ac04-808e-91491ee6441b.png)
ためしにレベル上でIndex15を「True」にしてみます。
![B12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/627ba985-a244-cf9c-9865-cf0ecf0583dc.png)
小節の終わりにのみキック音が連続で鳴るようになりました。


### ハイハット、スネアも再生してみる

他のドラム、ハイハットやスネアについても再生されるよう実装してみます。
既に作成している変数「Pattern_Kick」を右クリックして「Duplicate」（複製）します。
![C01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ed2b4fbe-ea63-2a00-a8d8-fcbb5dcc3c4a.png)
3つ複製したら、それぞれに名前をつけます。
![C02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/be3c9407-f39e-acb2-e7c9-164221a85089.png)
一度コンパイルし、初期値を適当に設定してみましょう。
次の画像はひとまずの設定例です。
![C03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/42acb2d9-f3d7-2081-30ba-56972bf3d3f9.png)

並行して各パートの再生が行われるよう、**Sequence**ノードを噛ませます。グラフの視覚的な整理にもつながります。
![C04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/7e1e7f91-d93b-31b3-67cc-42c93df89a89.png)
キック音と同じように処理を組みます。
複製してもいいのですが、参照する変数とサウンドを変更するよう注意してください。
![C05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/3bf75cba-e821-c549-113d-a078569e1ae5.png)
すべてのドラム音について同じように書いていきます。
![C06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/87feaf67-89a2-e627-ae59-b37e1605c97f.png)

キックに加え、ハイハットやスネアもパターンに応じて再生されるようになりました。
こちらも同じようにレベル上でカスタム可能です。


### 打楽器を差し替え可能にする

さらに、ドラムパターンで使用している音（キュー）を差し替え可能にしてみましょう。
使用する音を増やすため、AtomCraftに戻ってマテリアルを追加しました。
![D01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/06a91cf5-7b0c-2b84-543a-1c0d1bd23a41.png)
こちらも専用のキューをそれぞれに作成します。
（他にも、専用のキューを作らずAisacコントロールやキュータイプ「セレクト」でサウンドを変更する方法もあります）
![D02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9dda95b5-d0ea-1f39-c38b-098f4b241aed.png)
キューシートをビルドし、UEで再インポートします。
「Sound Atom Cue」型の変数を4つ追加し、それぞれに名前をつけます。
![D03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8a25d53e-6775-6529-9fe3-044cebbe6fa5.png)
ドラムパターン用の変数から続けて作った場合、配列変数として作成されるケースがあります。
タイプが「Single」になっているか確認し、それ以外なら手動で「Single」に設定しましょう。
![D04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/fa9bfc62-8a7a-3671-888f-61745154876e.png)
コンパイルし、初期値として基本のドラムサウンドを指定します。
![D04b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8a653cc1-20ac-6eac-a37c-b53385a2ef7b.png)
こちらも外部からアクセスできるよう変数を公開します。
![D05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/762bcf32-8c9e-9aa0-563f-a9f300feb477.png)
**Spawn Atom Sound 2D**ノードの対象として、この変数をつなげます。
これで現在指定しているサウンドが再生されるはずです。
![D06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a7f3f2d1-197a-806b-a89f-4145a810415f.png)
他のハイハット、スネアに対しても同じようにノードをつなげます。
![D07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d916b66e-14cd-93f7-c67a-714272125496.png)
変数を公開しているので、レベル上でサウンドを差し替えられます。
別のキューを指定すると、ドラムのサウンドが異なるものに置き換わりました。

![D08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/aa751baa-f1f7-fea5-1168-36239f9a185f.png)



### ランタイムでドラムパターンをカスタムする

今回作成したドラムパターンは変数として外部からもアクセス可能なので、別のブループリントやレベルブループリントから、キーやボタン入力に応じてパターン上のBoolのON/OFFが可能となっています。
![E01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c661119e-92d7-f401-6a86-1978f72056f0.png)

冒頭で紹介したように、レベル上にスイッチを置いておきランタイム上でドラムパターンを編集する、という遊びも実現できてしまいます。
ゲーム中の敵の数に応じてドラムの密度が上がったり、パズルのギミックの一部に組み込んでみても面白いかもしれません。