ゲーム中の複数キャラボイス管理テクニック(ADX2 for UE4)

# はじめに
UE4.23+「ADX2 LE v2.10.05」を使用します。
アンリアルエンジン4とサウンドミドルウェア「ADX2 for UE4」を連携させ、
ゲーム内で複数のキャラクターボイスを切り替えて扱う際の再生管理を容易にします。


# 前提
「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側の作業

### 複数のキューシートを作成する
今回扱う処理は実にシンプルで、**異なるキューシートで同じ名前のキューが共存できる**ことを利用して動的にサウンドを差し替えるものです。
![Intro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0228e777-082f-dde8-15b7-7613e118b8ff.png)
キューシートは「キャラクターボイスリスト」で、キューは「ボイスデータ」そのものとして考えられます。
キャラAとキャラBのボイス再生処理はまったく同じものを使用していながら、それぞれのキャラクターが持つ「ダメージ」時などボイスを再生しています。

サンプルとして、ワークユニットツリーにキャラクター2人のキューシートを作成します。
![A01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/54107016-9cf6-95ad-c368-f63f4c6dcfb2.png)
![A02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b5dbae54-5712-236d-a15e-a0233dcad829.png)
各キューシートに**同じ名前**のキューを作成します。
作成するキューのタイプは特別な処理がなければ「ポリフォニック」です。
![A03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/48f44480-4692-1a84-62f6-8a985a18d01b.png)
片方のキューシートに作成したキューをコピペしてしまえば楽かも。
![A04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b83b00e1-6f29-f605-721b-ff663083ae45.png)
![A05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f019e6ba-42a4-9f34-9eb8-3a5e9d69e58a.png)

キューに対して、対応するボイスのサウンドを入れます。
![A06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1b2d603f-60b5-595c-aa22-ccf494c821ff.png)
再生ボタンを押して、キューとボイスが正しいか確認すると安全です。

### キューシートのビルド
AtomCraftでの作業はこれで完了ですので、キューシートをビルドします。
![A07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8d2a65f6-c52e-57b3-afb6-783d1c588066.png)
**すべてのキューシートにチェックがついている**ことをチェックしてからビルドします。


## UE4側の実装

### キューシートのインポート
ビルドしたデータをすべてインポートします。キューシートごとに分割されたファイルとして吐き出されているので、インポート漏れがないように注意してください。
![B01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/159db3f8-7b8a-1ebe-6f1b-a2ef35b10384.png)

### Atom Configファイルの設定
Project SettingsのCriWareタブで、今回使用するAtom Configファイルを設定します。
![B02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/39faad56-282a-264c-1a9a-6a8bba925aaf.png)

### ブループリントでキャラクターボイスを再生する
導入編の記事ではレベルに直接Atom Cueを置いて再生していましたが、配置していない音声も再生できるよう、その場でボイスデータを取得してロードしてみましょう。
暫定としてレベルブループリントに処理を書きます。
「Load Atom Cue Sheet」でキューシートを呼び出します。「Cue Sheet」は作成したキューシートのうち、どちらか片方のキャラクターのものを指定します。
![B03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b9a454cf-fa78-a8d6-b152-f5c2a744122a.png)
「Get Atom Cue by Name」でAtom Cueにアクセスします。「Load Atom Cue Sheet」のReturn ValueからTargetの青ピンにつなげます。
これはキュー名で取得するノードですので、再生したいキュー名を入力します。
![B04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/3dae0af9-5d4c-79ab-79e8-f57fb60c9c4c.png)
「Play Sound at Location」ノードで実際に再生します。再生場所は「Get Player Character」で取得したプレイヤーキャラの座標にしています。
![B05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/09c9f144-e500-7485-06a0-9acfc9a5d666.png)
もっと厳密に指定するなら、キャラクターメッシュの口部分にソケットを仕込んでおき、その座標を取得するのがいいでしょう。

この時点でゲームを再生してみると、Tキーを押すとキャラクターの声が流れます。


### その他のキューシート、キュー取得法
「Load Acb」ノードを使えば、Acbファイル名を指定して直接キューシートを読むことができます。
![B08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0a258888-7154-b400-35ec-11ba4d5fea81.png)

「Get Atom Cue by Name」以外にも、「Get Atom Cue by ID」や「Get Atom Cue by Index」を使うことでキューのIDやインデックスを指定してアクセスすることもできます。
![B06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/94586d4d-0c18-2da0-1d7a-b77cdaa8ba68.png)
![B07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/6dcf2e6f-a1a5-9765-8f01-a0c637de532f.png)

### キューを差し替えてキャラクターボイスを変更する
ゲーム中にリアルタイムで参照するボイスを切り替えてみます。
以下はなんの変哲もない、「1」キーを押したらキューシートをロードする処理です。
![B09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1cb87d49-2c60-d576-d475-5c8d7ccfb1f6.png)
「Return Value」の**ピンを右クリック**して「Promote to Variable」をクリックし、ロードしたキューシートを変数化します。
![B10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/76203293-ca7d-b9f2-e60f-42438eca13fe.png)
Sound Atom CueSheetタイプの変数が出来上がるので、名前を適当につけます。
![B11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/23968ce2-61fa-2233-b24f-3faa9cf39d86.png)
同じように処理を作り、1キーを押したらキャラクターAのボイスが載ったキューシートが、2キーを押せばキャラクターBのボイスが載っているキューシートが読まれるようにします。どちらも変数「Current Cue Sheet」を上書きされるので、最後に読んだキューシートが参照されます。
![B12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/0b100bf5-4e64-673f-f69f-8cc9cbd0e672.png)

あとは先ほどと同じようにボイスを再生します。
![B13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/dfcab7ec-c671-e753-fe86-5234cc63d702.png)

この状態でゲームを再生すると、1キーを押した状態だとキャラクターAの、2キーを押した状態だとキャラクターBのボイスが流れます。
ゲームは同じ「ダメージ」を受けた状態でも、読んでいるキューシートによって違うキャラクターの声が再生されるわけです。
上記の「Load Acb」ノードを使えば文字列でキューシートを指定できるので、より多くのキャラクターが登場する場合に便利です。

### 補足
キューシートさえ読んでしまえば、ブループリントノードからAtom Cueを読み出すことが可能です。
アセットにキュー自体が含まれていなくても、ゲーム中にその場でキューを再生できます。