ADX2+UE4で作る、パーシスタントレベルの切り替えでも途切れないサウンド再生

# はじめに
アンリアルエンジン4とサウンドミドルウェア「ADX2 for UE4」を連携させ、
ゲーム側での設定に応じて再生する効果音を一括で切り替える実装についてです。

当記事ではUE4.23+「ADX2 LE v2.10.05」を使用します。基本的にブループリントのみでの実装を想定しています。

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

# 実装

## パーシスタントレベルのみを使用する実装

### ノードによる、レベルをまたぐ再生処理
普通に音声を再生した場合、**Open Level**ノードでレベルを切り替えた際に、再生中のサウンドが一括で停止されてしまいます。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/65944619-1363-c851-4df9-3cb896014018.png)
次のノード例ではBGMを再生（**Spawn Sound at Location**）した直後にレベルを切り替え（**Open Level**）しています。
この場合、BGM再生直後にロードが入り、音声は途中で途切れてしまうでしょう。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/16bdac39-b857-df14-39b9-a2b720cf056c.png)

レベルを切り替えてしまっても再生を続けるには、**Create Rooted Atom Component**を使います。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9889ad91-059e-8987-e1c2-c83d38bdf55b.png)
これだけではAtom Componentをゲーム中に作成するだけなので、**Set Sound**ノードなどで再生したい音声を設定してあげた後、
**Play**ノードで実際に再生を開始する必要があります。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0793c397-2cb8-cc37-d615-5f0a815216e4.png)
従って、以下の例ではレベルを切り替えてもサウンドが再生され続けます。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d997f15f-ea7b-8f9e-befa-35b84f8a90b6.png)

### Rooted Atom Componentの再生を停止する
さて、この場合**Create Rooted Atom Component**ノードの「Auto Destroy」にチェックが入っていれば再生終了とともにAtom Componentが破棄されますが、手動で再生を停止したい場合一工夫必要です。
生成したAtom Componentの参照は、予め変数として格納しておくか、後でインデックスなどから取得する必要があります。
普通の手段で変数に格納しても、レベルの切り替えと同時に参照が外れるケースが多いです（レベルブループリントやアクターが持つ変数など）。
パーシスタントレベルを切り替えても値を保持するゲームインスタンスなどで変数を保管してしまうのがいいでしょう。

任意のゲームインスタンスクラスがない場合、新しく作ります。
コンテンツブラウザの適当な場所で右クリックし、「Create Basic Asset」→「Blueprint Class」を選択します。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8b470fc0-181e-b838-4b6e-3ce6ac2a81b1.png)
親クラスを選択するウィンドウが出るので、下部の「All Classes」を押してメニューを拡張します。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a67e0a34-04b7-d19b-55b1-06d08d18c954.png)
**「GameInstance」**を検索して選択します。「Select」を押すとクラスが作成されます。
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/6f0c2830-4036-0ad2-3f1b-b8c127d4e9b2.png)
名前をつけておきます。
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0e292596-adab-ba12-d2b7-b9cd721dec38.png)
ダブルクリックして開き、「My Blueprint」パネルで変数を追加します。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/98453deb-2083-c7ff-d00f-1cf5f9a2b7b5.png)
Variable Typeは**「Atom Component」**とします。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/102941ae-d88a-d1cd-d421-95e622932a21.png)
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/e3bfa428-5e47-38fa-fcd9-93a0153aaa31.png)
ツールバーの「Edit」→「Project Settings」を開きます。
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8466acb4-0847-be08-af5e-156b903b44e7.png)
「Maps&Modes」→「Game Instance Class」に作成したゲームインスタンスを指定します。
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c1398832-4619-e7a0-5cce-9f1cd9410951.png)
これでゲーム中に使用されるゲームインスタンスが設定できました。この中にAtom Componentを格納すれば、レベルを切り替えても値が破棄されなくなります。

**Open Level**ノードでレベルを切り替える処理に戻ります。
ゲームインスタンスに変数をSetするには、次のようなノードを組みます。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b371210f-4abf-2709-18ca-405b20f0ea6a.png)
これを既存の再生→レベル切り替え処理に組み込みます。
少し分かりづらいですが、次の画像のようになります。
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/64c85b39-36c3-64cf-1ca5-0b2cd8c166fb.png)
切り替えた先のレベルで、再度ゲームインスタンスを参照し**Stop**ノードなどで再生を終了するなどの操作をすることが可能です。
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9c2486e5-7a95-f8c6-a836-a684c3eb086b.png)