はじめに
ADXアンバサダーとして記事を書いておりますSigと申します。
この記事ではUE5で作るVRプロジェクトにおける、「ハンドコントローラ操作に伴うサウンド」を実装します。
VR特有の要素として「手をトラッキングできること」があるでしょう。
ユーザー操作のフィードバックとしてサウンドを効果的に使うことで表現力の幅が広がります。
この記事では、サウンドによるフィードバックとして次のような携帯電話を例として実装を行います。
- 携帯電話のメッシュ位置から着信音を鳴らす
- 手に持って耳元に近づけると、
- 着信音が切れ通話が聞こえる
段階式のイベント演出の一例としてご覧ください。
また、記事最後に「blueprintue」を使用したBPグラフ共有を載せています。コピペするだけで大体の実装ができますので、よろしければご活用ください。
当記事ではUE5.6 及び 「ADX LE UE SDK(2.04.02)」を使用します。
また、基本的にブループリントのみでの実装を行います。
ADX for UEはインディー向けの「LE版」であれば、無料で使用できます。
https://game.criware.jp/products/adx-le/
前提
「ADX for UE LE」を使用します。導入や簡単な使い方は以下の記事にあります。
ADX for UEの導入で、一歩上のサウンド表現を(導入編)
ADX for UEの導入で、一歩上のサウンド表現を(実践編)
実装
AtomCraftでサウンドを用意する
今回は実装サンプルとして、
- SE_PhoneCall.wav 電話の呼び出し音
- CV_Male_PhoneA_01.wav 電話口から聞こえる、登場人物の話し声
の2つのwavファイルを用意しました。
AtomCraftを開き、マテリアルとしてマテリアルツリーにインポートします。

呼び出し音だけはインスペクターにてループタイプを「ループ」に設定し、電話を取るまで再生され続けるようにします。

キューシートを右クリックし、「新規オブジェクト→『ポリフォニック』の作成」を選択してキューを新規に作成します。

もしくは、マテリアルツリーからキューシートにドラッグ&ドロップすることでもポリフォニックタイプのキューを作ることができます。
通常の用途のキューをまとめて作る場合、この方法が便利です。

すべての音源についてキューを作ります。

すべてのキューにおいて、インスペクターにてパンタイプを「3Dポジショニング」にします。

電話口での声の聞こえ方などを調整するため、ツールバーの「表示」→「セッションウィンドウ」を呼び出します。

キューをセッションウィンドウ下部にドラッグ&ドロップして登録します。

セッションウィンドウ上部の「3Dポジショニング」を有効にします。

キューを再生し、「プレーヤーに3Dオブジェクトをアタッチ」にチェックを入れます。
緑色の領域をドラッグして聞こえ方を確認します。

話し声を確認してみると、だいぶ遠くからでも聞こえてしまいます。

話し声のキューを選択し、インスペクターにて「3Dポジショニング」のボタンを押します。

距離減衰の値を調整します。

この状態では少し離れると音が減衰し、聞こえなくなりました。

数値を調整するとセッションウィンドウの円の範囲が変わります。目と耳で確認しながら調整してみましょう。

角度による減衰も設定可能です。VR空間では特に効果が大きいので、重要な効果音では設定してみてもいいかもしれません。
UE5にインポートする
ビルドしたacb, acfファイルをUE5にインポートします。
コンテンツドロワー(コンテンツブラウザ)にドラッグ&ドロップします。
ダイアログでは「Yes」を選択します。
これにより、acfファイルがプロジェクトに自動的に設定されます。

Atom Config、Atom Cue Sheetアセットが作られます。

レベル上にドラッグ&ドロップし、正常に再生されることを確認します。

確認が終わったらレベルから取り除いておきましょう。
電話アクターを用意する
新規にブループリントクラスを作成します。
コンテンツドロワーで右クリックし、「Bueprint Class」を選びます。

親クラスは「Actor」を選択。

名前をつけます。今回は「BP_Phone」としました。

ダブルクリックして開きます。
「StaticMesh」コンポーネントを追加し、適当なメッシュを割り当てます。
スケールを設定し、手に持てるようなサイズにします。

「Add」ボタンから、「Grab Component」を追加します。
これにより、このアクター(が持つメッシュ)をハンドコントローラーで掴むことができるようになります。

メッシュやコンポーネントの位置、スケールを整えます。

StaticMeshコンポーネントを選択し、Detailsパネルの「Simulate Physics」にチェックを入れます。
物理演算が有効になり、手から離すと重力に従って落下するようになります。

レベル上に配置します。VR Previewを起動し、掴むことができるか確認してみましょう。

電話オブジェクト(呼び出し音)
電話のブループリントに、Atom Comopnentを追加します。これは電話の呼び出し音の再生に使用します。

AtomコンポーネントとGrabComopnentはStaticMeshコンポーネントの子になるようにします。

Atomコンポーネントにサウンドを設定します。

電話の呼び出し音はイベントから再生するので、自動再生を無効にします。
Auto Activateのチェックを外します。

イベントグラフにて、カスタムイベントを追加します。

イベント名は「StartCall」としました。

Atomコンポーネントを再生するだけの単純な処理です。
もし今後演出を拡充するのであれば、電話の画面を表示したりなどといった処理をここに書いていくことになるでしょう。

レベルブループリントを開きます。

ゲーム開始から5秒待機し、イベント「StartCall」を呼び出す処理を用意しました。

ゲームを再生して電話が鳴り出すことを確認します。
もしVR Previewを使用せずに動作を確認する場合、ゲーム再生中にOutlinerパネル上に出現する「SpectatorPawn」を移動させることでサウンド聴取位置を変えて確認することができます。

電話オブジェクト(話し声)
電話のBPに、新たにカスタムイベント「StartSpeak」を追加します。
これは電話を取るとコール音が止み、話し声が聞こえてくるというイベントです。

Stopノードでコール音を停止させます。
Spawn Sound Attachedノードを配置します。必ず「Atom」カテゴリのものを使用します。
もう片方はUEデフォルトのノードなので、キューの再生はできません。

Spawn Sound Attachedノードで再生するキューシート及びキューを選択します。

Event Begin Playにて、オブジェクトを掴んだときのイベントを登録します。
Grab Comopnentを対象に、Bind Event on On Grabbedノードでイベントを登録できます。

赤いインプットピンから線を伸ばし、Create Eventノードで対象のイベントを指定します。
今回の場合は「StartSpeak」です。

電話オブジェクト(話し声の停止)
また、電話を手から離した際のイベントも作ってみましょう。
Spawn Sound Attachedノードの「Return Value」を右クリックし、「Promote to Variable」で変数として登録します。

「Speak Sound」と名前をつけました。変数として格納しておくことで、後で任意のタイミングで再生を停止できます。

カスタムイベント「Stop Speak」を作成し、Stopノードで変数として格納した「SpeakSound」を停止します。

掴んだときのイベントと同じように、Bind Event to On Droppedで手を離した際のイベントを登録します。

このままだと、話し声が再生されていないタイミングで手を離すと変数「SpeakSound」が参照できないというエラーが出ます。気になる場合は、Is ValidノードとBranchノードを使い、変数が有効かを判定しておくと安心です。

こういったプレイヤーのアクションに応じて起動・変化するイベントを盛り込んだ演出を入れることで、プレイヤー自身の手でゲームを進めている感を強化できます。
補足
サウンドの減衰設定は、AtomCraftだけでなくADX for UEによる「Atom Attenuation」アセットでも設定可能です。
こちらはエディタ上で調整が可能なので、ワークフローによってはこちらを使う方が楽なケースもあります。
こちらの記事に、「Atom Attenuation」を設定する方法があります。
今回のグラフ
「blueprintue」にて、今回のサンプルとなるグラフを公開しています。
そのままコピペすればノードを流用できますので、ぜひご利用ください。
https://blueprintue.com/blueprint/dzqcfxat/

