はじめに
ADXアンバサダーとして記事を書いておりますSigと申します。
この記事ではアンリアルエンジン5とサウンドミドルウェア「ADX for UE」を使い、UI(UMG)上のカーソル操作に伴うサウンドを再生する実装例を紹介します。
ボタンやキーの入力を取得してカーソルを操作する際、順送りか逆送り、またメニューの先端でのループ時にサウンドを変化させ、聴覚からのフィードバックを多彩にします。
前提
UE5.4+「ADX LE UE SDK(2.03.00)」を使用します(他バージョンにおいても、基本的に実装方法は同じです)。
基本的にブループリントのみでの実装を想定しています。
ADXはインディー向けの「LE版」であれば、無料で使用できます。
https://game.criware.jp/products/adx-le/
なお、ADX2からADXへ名称が変更になりましたが、ツール構成は変更ありません(2がないから古いほう、というわけではありません)。
ADX for UEの導入や基本的な使い方は以下の記事にあります。必要に応じて参照してください。
ADX for UEの導入で、一歩上のサウンド表現を(導入編)
ADX for UEの導入で、一歩上のサウンド表現を(実践編)
実装
AtomCraftでサウンドバリエーションを作成する
UI上で再生するためのサウンドをAtomCraftで設定します。
ひとつだけサウンドを用意し、AISACコントロールによりピッチを変更して音を変化させます。
AISACコントロールを追加する
まずはピッチを調整するためのAISACコントロールを追加します。
プロジェクトツリーの「AISACコントロール」のフォルダ内で未使用の「AisacControl」を選択し、F2キーでリネームします。
キューを作成する
カーソル音用のキューを作成します。キューのタイプは用途に合わせて変更してください。今回は単純に「ポリフォニック」で作成しました。
キュー内にマテリアルをドラッグ・アンド・ドロップし、サウンドが再生されるようにします。
AISACコントロールを設定する
キューにAISACコントロールを設定していきます。
キューを右クリックし、「新規オブジェクト」→「AISACの作成」を選択します。
AISACの追加ダイアログではグラフタイプを「ピッチ」に変更します。
出現した「AISACリスト」の「ピッチ」を選択するとグラフが操作可能になります。
まずはグラフ上を適当にクリックして4つのコントロールポイントを追加し……
右のインスペクターをタブ切り替えで「ポイントリスト」表示にし、パネルで数値を入力して微調整するといいでしょう。
0~0.3では低いピッチ(カーソル順送り)、0.301~0.7では通常のピッチ(汎用音)、それ以上であれば高いピッチ(カーソル逆送り)としました。
さらに端にコントロールポイントを追加し、カーソルが端でループした際の変化を追加します。
例ではさらに低いピッチとしました。
キューを再生しながら、上部のスライダーでAisacコントロールの動作を試してみましょう。段階的にピッチが変化しているでしょうか?
キューシートのビルド
ここまでできたらキューシートをビルドします。
これでAtomCraftでの工程は完了ですので、UEに移りましょう。
UEでの実装
キューシートのインポート
ビルドしたキューシートをインポートします。
コンテンツブラウザ(コンテンツドロワー)の適当な場所にacf, acbファイルをドラッグ&ドロップしてインポートします。
その際のダイアログでは「Yes」を選択します。
2種類のアセットが作られました。
キューシートを開き、キューが再生できることを確認します。
キー・ボタン入力を登録する
UE5の新しい入力システム「EnhancedInput」を使用する、ボタン入力を登録して使用します。
UIを準備する
操作するためのUIを準備します。
コンテンツブラウザ(コンテンツドロワー)の適当な場所で右クリックし、「User Interface」→「Widget Blueprint」を選択します。
親クラスは「User Widget」を選択します。
名前をつけ、ダブルクリックして開きます。
メニューが並んでいる簡単なサンプルを用意しました。
「Canvas」を下地に、「Image」「Text」を使用して作っています。
テキスト「メニューA」の場所にあるシアンのバーがカーソルとなり、キー入力に合わせて動く想定です。
ウィジェットの入力処理
UI側に入力を反映させる処理を書いていきます。ここの処理はいろいろな方法があり、プロジェクトによっても変わってくるところなので、ここでは簡単に試せる処理を書いていきます。
この記事では最終的に「レベルブループリントで入力処理を受け取り、UIにカスタムイベントとして伝達する」手段をとります。
Detailsパネルでカスタムイベントにパラメータを追加します。
パラメータのタイプを「Integer」にし、適当な名前をつけます。これがカーソルの移動量になります。
ふたつのInteger型変数を追加し、現在のカーソル位置と項目の最大数とします。
変数「MaxCursor」を選択し、「Default Value」を「3」にしておきます。
選択肢が4つのため、カーソルの値は「0~3」で変動する想定です。
カスタムイベント「CursorMove」の入力を受け取り、カーソルの現在値に加算します。
Clampノードを噛ませると簡単に最小・最大数に制限がかけられて便利です。
Event Tickから、カーソル画像の表示位置をカーソルの現在値に合わせてずらす処理を追加します。
レベルブループリントを開きます。
Event BeginPlayでウィジェットを追加します。
追加したウィジェットのアウトプットピンを右クリックし、「Promote to Variable」で変数として格納します。
変数に適当な名前をつけます。
先ほどプロジェクトに登録したカーソル入力を取得し、上であれば「-1」、下であれば「+1」をウィジェットのカスタムイベント「Cursor Move」に渡します。
UIが表示され、キー入力に合わせてカーソルが動くようになりました。
サウンドを再生する
実装したカーソル移動に合わせてサウンドを再生します。
カーソル音を再生する
ウィジェットのカスタムイベント「CursorMove」の処理の最後にSpawn Sound 2Dノードを追加し、カーソル移動音を指定します。
同名のノードがありますが、「Atom」カテゴリのものを使用します。
再生するキューシートを選択し、キューを選択します。
AISACコントロールを操作してカーソル音のピッチを変化させます。Set Aisac Control Valueノードを使用します。
入力の値はカーソルの移動方向によって変わるので、Selectノードを使います。
少しややこしいのですが、Selectノードは入力(0~n)の値によって異なる出力を設定できます。
インデックス番号が0~になるので、カーソル移動量に+1をし、その値に合わせてインデックスを設定していきましょう。
難しければ次の画像の通りにノードを組んでみてください。
これで、カーソル操作時に移動方向によって音が変化するはずです。
カーソルがループした際のサウンドを変化させる
カーソルが一番上もしくは下に来た際、カーソル位置を反対方向にループさせる処理です。
「CursorMove」の処理を大幅にリフォームします。
どちらにもループしなかった場合、通常のカーソル音処理を付け足して完成です。