1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UE5 + VR + ADXで作る、視線誘導のためのインタラクションとサウンド

Last updated at Posted at 2025-09-09

はじめに

ADXアンバサダーとして記事を書いておりますSigと申します。
この記事ではUE5で作るVRプロジェクトとADX for UEを併用し、「視線によるUI選択とそれに伴うサウンド」を実装します。
VRゲームではそのデバイスの性質上、視線による判定(トラッキング)も可能です。
視線を利用したインタラクションにサウンド効果をつけ、リッチなUI演出を作ってみましょう。

やること

  • 3D空間上にボタンを作る
  • 視線をボタンに合わせると決定音を再生する
  • 視線がボタンに合っていないときはボタンからかすかなループサウンドが再生される
  • ループサウンドは、視線がボタンに近づくとはっきりと聞こえるようになる

聴覚でボタンの位置をプレイヤーに伝え、視線が近づくにつれ音の存在感を増すことで聴覚から視線を誘導します。

また、記事最後に「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でサウンドを用意する

まずは効果音を用意します。
ふたつのwavファイルをマテリアルツリーにインポートしました。

  • 「SE_UI_Decide.wav」: 視線をボタンに合わせたときの決定音
  • 「SE_UI_PreDecide.wav」: 視線がボタンに近づくにつれ大きくなる誘導音
    A01.png
    誘導音はループさせたいので、選択してインスペクターでループタイプを「ループ」にしておきます。
    A02.png
    キューシートを右クリックし、キューを作成します。
    「新規オブジェクト」→「キュー『ポリフォニック』の作成」です。
    A03.png
    ふたつのキューを作り、マテリアルツリーからドラッグ&ドロップしてトラック上に配置します。
    A04.png

ふたつのキューはインスペクターでパンタイプを「3Dポジショニング」にします。
空間上で距離減衰がかかるので、どこから聞こえてくるかでボタンの方向が分かりやすくなります。
Aex.png

誘導音のキューを選択します。
トラックリストの空欄で右クリックし、「新規オブジェクト」→「AISACの作成」を選択します。
Aisacコントロールを使い、視線とボタン方向の角度の差によってボリューム、フィルタを操作して聞こえ方を変化させていきます。
A05.png
AISAC名、グラフタイプを設定します。
A06.png
グラフを操作し、画像のような右肩上がりの形にします。
A07.png
「ポイントリスト」に直接数値を入力することで値をしっかりとデザインすることができます。
A08.png
タイムラインに戻り、もうひとつのAISACを作ります。今度のグラフタイプは「バンドパス - Cof低域」です。
この値が大きいほど広域がカットされる(低域だけが通される)ので、誘導音が聞こえにくくなります。
A09.png
「Aisacコントロールの数値が高いほど視線が近い」という法則でロジックを作るので、右に行くほどボリュームは高く、バンドパスのフィルタは低くしていきます。
A10.png
再生して、上部のスライダーを動かしながら聞こえ方を確かめましょう。
実際にはこの2つの数値は「視線方向」というひとつのパラメータで操作しますので、連動するイメージです。
A11.png

ここまでできたらキューシートをビルドし、エクスポートします。
A12.png
A13.png

キューシートのインポート、テスト再生

ビルドしたacb, acfファイルをインポートします。
コンテンツドロワー(コンテンツブラウザ)にドラッグ&ドロップして配置します。
ダイアログでは「Yes」を選択します。
B01.png
2つのアセットがあることを確認します。
B02.png
キューが再生されるか確認してみましょう。ドラッグ&ドロップでレベル上に配置します。
B03.png
Detailsパネルの「Control Modulations」でAisacコントロールの値のテストができます。
+ボタンを押して項目を追加します。
B04.png
AisacControl_00とAisacControl_01の値を変更し、再生してみましょう。聞こえ方が変わっていれば成功です。
B05.png

ボタン用アクターの作成

ボタンとなるアクターを作成します。
コンテンツドロワーの適当な場所で右クリックして、「Blueprint Class」を選択。
C01.png
親クラスでは「Actor」を選択します。
C02.png
名前をつけます。視線で選ぶメニューなので、今回は「BP_SightMenu」としました。
C03.png
ダブルクリックして開、StaticMeshとTextRenderコンポーネントを追加します。
位置やサイズ、パラメータを調整し画像のようにボタンにします。
座標を管理しやすくするため、中心部が原点になるようにするとベターです。
C04.png
視線による当たり判定はTrace系のノードを使用します。
専用の当たり判定チャンネルを作りたいので、Project Settingsに移動します。
C05.png
「Collision」タブに移動します。
C06.png
「New Trace Channel」を押してトレースチャンネルを追加します。
C07.png
名前をつけ、Default Responseは「Inogre」(無視)とします。
基本的にオブジェクトはプレイヤーの視線に反応せず、特定のものだけに適用したいためです。
C08.png
トレースチャンネル「SightMenu」が追加されました。
C09.png
ブループリントアクターのメッシュのCollsiion Presetsを「Csutom」にします。
C10.png
「SightMenu」の反応を「Block」にします。これにより、このメッシュがトレースチャンネル「SightMenu」に反応するようになります。
C11.png
レベル上の適当な場所にアクターを配置します。
C12.png

視線合致の判定

プレイヤーがボタンを見たときに効果音が再生されるロジックを組んでいきます。
ここからの処理はプレイヤー側のBPで行うと取り回しがいいですが、実装サンプルとして簡易にするためこの記事ではボタン側のBPで行います。
プレイヤーのBPを取得し、キャストします。
D01.png
アウトプットピンを右クリックして「Promote to Variable」で変数化します。
D02.png
Tickイベントにて、Line Trace By Channelで当たり判定を飛ばします。
D03.png
プレイヤー座標からプレイヤーの見ている方向に判定を飛ばします。
ノード構成はこのようになります。
D04.png
入力ピンの色(型)が合わない場合は、右クリックしてピンのタイプを変更できます。
D05.png
Trace Channelを「Sight Menu」にします。
また、「Ignore Self」のチェックを外します。そのままでは当たり判定がこのアクター自身を無視してしまうためです。
D06.png
トレースが反応したかどうかを判定します。
D07.png
変数を新しく作ります。型はBoolです。これは視線によるインタラクトが完了しているかどうかを記憶するためのものです。
D08.png
「bInteracted」がFalseの場合のみ処理を行います。「bInteracted」をTrueにします。
D09.png
Play Sound at Locationノードで効果音のキューを再生します。
必ず「Atom」カテゴリにあるものを使用します。同名のもう片方のノードはUEデフォルトのものなので、Atomキューは再生できません。
D10.png
再生するキューを選びます。
D11.png
視線がメッシュにヒットすると、一度だけ決定音が流れます。
D12.png
Line Trace By ChannelノードのDraw Debug Typeを「For One Frame」にするとデバッグ用の視線描画が行えます。
ただしラインはまっすぐ飛んでいるため、VRの一人称では視界の真ん中に点が表示されるだけです。
エディタ表示で横から見てみると分かりやすいと思います。
D13.png

ファジーな視線判定

「視線の近さ」を判定し、それが近いほど音を変化させていくアプローチを行います。
Tickイベント内で処理を行いますが、ノードを整理するためSequenceノードを置きます。
E01.png
視線の角度判定の流れはこのようになります。

  • 視線ベクトルを取得する(現在のベクトル)
  • プレイヤー座標からボタンがある方向へのベクトルを取得する(目標ベクトル)
  • ふたつのベクトルをDot Productノードで比較する
  • ベクトルが一致しているほど、AisacControlの値を高くしてサウンドを変化させる

ふたつのベクトルはこのようなノードで取得できます。
E02.png
Dot Productノードを使います。これは2つのノードを比較し、同じ方向であれば1.0に近く、反対方向であれば-1.0に近い値を返すノードです。
E03.png
試しにPrint Stringノードを使い、Dot Productの結果を出力してプレビューしてみましょう。
毎フレーム出力するので、Durationは「0.0」にしておきます。
E04.png
画面左上に数値が表示されます。
視線がボタン方向に一致していると1.0に近く……
E05.png
別の方向では低い数値になります。
E06.png
反対方向では-1.0に近い数値になります。
E07.png
この数値を利用してAisacに渡していきましょう。
誘導音を再生するAtomコンポーネントを追加します。
E08.png
キューを指定します。
E09.png
Dot Productは「-1.0~1.0」の数値を返しますので、その結果をMap Range ClampedノードでAisacControlの数値である「0.0~1.0」に変換します。
この数値をSet Aisac Control Valueノードに渡します。
ボリュームとフィルタの2種類のAisacControlがあるので両方とも使用します。
E10.png
決定音の再生時に、誘導音を停止します。
E11.png

これで視線によるインタラクションと、音による誘導が実装できました。
「視線がどの程度一致しているか」というギミックはUIだけでなく、様々なVRゲームのシチュエーションに流用できるものです。ぜひ使用して、VR空間における頭や視線の動きをデザインしてみてください。

今回のグラフ

「blueprintue」にて、今回のサンプルとなるグラフを公開しています。
そのままコピペすればノードを流用できますので、ぜひご利用ください。
https://blueprintue.com/blueprint/5xpa_036/

1
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?