0
0

More than 3 years have passed since last update.

UE4+ADX2で、ランダムに繋がるBGMをシームレス再生する

Last updated at Posted at 2021-03-12

はじめに

アンリアルエンジン4とサウンドミドルウェア「ADX2 for UE4」を連携させ、BGMのフレーズをランダムで選定してプロシージャルなBGMを再生します。

「シームレス連結再生」を使い、BGMの任意の部分をランダムに演奏します。これにより、イントロとアウトロは毎回同じなのに、中間のメロディが毎回違うBGMを再生することが可能になります。統一感を保ったまま、ユーザーに飽きにくいBGMを提供することができるでしょう。

当記事では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にタイミング情報を設定する

BGMのフレーズをシステム側で選ぶにあたって、次のフレーズを確定するタイミング情報をAtomCraftを使って埋め込みます。
現在のゲーム状況を反映させるのであれば、遅ければ遅いほどシチュエーションがBGMに反映されることになるためベターかと思います。

今回はイントロ用、アウトロ用のフレーズと、曲前半用に4種、曲後半用に2種で計8フレーズ用意しました。
A01.png

キューを作成する

キューを作成します。基本的にタイプは「ポリフォニック」です。

A02.png
キュー名に対応したマテリアル(音源)をトラックにドラッグアンドドロップします。
A03.png
すべてのキューに対し対応するマテリアルを入れていきます。
A04.png

キューシートのビルド

完了したらキューシートをビルドします。
A09.png
A10.png

UE4でBGMをランダムに繋げる

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

ビルドしたキューシートをインポートします。
UE4のコンテンツブラウザにacf, acbファイルをドラッグアンドドロップします。
B01.png
ツールバーの「Edit」→「Project Settings」を開き、acfファイルを今回出力したものに変更します。
B02.png
B03.png

ブループリントからBGMを再生する

BGMを再生するためのアクターを作成します。
コンテンツブラウザで右クリックし、「Blueprint Class」を選択。
B04.png
「Actor」クラスを親にして作成します。
B05.png
名前は「BP_RandomMusic」としました(分かりやすければ何でも大丈夫です)。
B06.png
ダブルクリックして開きます。
「+Add Component」から、「Atom Component」を追加します。
B07.png
「シームレス連結再生」の機能を使うためには、Atom Componentを選択しておき、Detailsパネルで「Use Playlist」のチェックボックスをTrueにします。
B08.png
イベントグラフに移ります。
Event BeginPlayから、Set Soundでイントロとなるキューを指定します。
Playノードで再生を開始します。
B09.png
アクターをレベルに配置して再生すれば、イントロ部分のフレーズが自動的に流れるはずです。

シームレスにキューを繋げる

キューの再生終了時に繋げてキューを再生するには、Enqueue Soundノードを使います。
B10.png
Enqueue Soundノードを重ねるとプレイリストに追加していく要領で、次に繋がるキューが蓄積されていきます。Set Soundノードでプレイリストをリセットすることができます。

再生終了前に次に再生するフレーズをランダムに選ぶ

次に再生するキューを格納するための変数を作ります。
Enqueue Soundキューの「New Sound」キューを右クリックし、「Promote to Variable」をクリックして変数化します。
B11.png
名前は「Next Cue」としました。
B12.png
変数のタイプが「Sound Atom Cue」になっていることを確認し、Default Valueに適当なフレーズを設定しておきます。
B13.png
次に、再生するフレーズを選ぶ処理の時間と、時間のカウントをするための変数をそれぞれ追加します。
どちらもFloat型変数です。
B14.png
「Sound Atom Cue」型の変数から線を伸ばし、Get Durationノードを置くことでキューの再生時間(長さ)が取得できます。
B15.png
今回は「再生終了時間 - 3秒」のあたりで次のキューをランダムに選ぶことにします。予定時間を「Next Phrase Time」に格納します。
B16.png

次に再生時間をカウントし、実際にフレーズを選ぶ処理に移ります。
Tickイベントから処理を開始し、Countを加算していきます。値が「NextPhraseTime」を超えたらカウントをリセットし、フレーズのランダム処理を走らせます。
B17.png
まず次のフレーズを確定→その後次のフレーズの再生時間を取得という流れを作りたいので、Sequenceノードを使います。
B18.png
「Then 0」からは「Next Cue」にランダムな値を設定し、
B19.png
「Then 1」からはEnqueue Soundでシームレス連結再生機能にアクセスし、「Next Phrase Time」を再計算します。
B21.png

一定数の再生で曲の展開を変える

一定数演奏したら、曲の展開を変える処理です。
Int型の変数「PhraseCount」を作り、フレーズを選ぶごとに加算します。
B22.png
B23.png
Branchノードで、一定再生数ごとに分岐を作り、サビやアウトロが再生されるようにします。
B24.png

補足

扱うキューの数が多い場合、データテーブルを使って管理・取得するのもいいかもしれません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0