【UE4・UE5】VR開発では必修!アクター間の相対位置の求め方+キャラクターがどっちから触れたかの応用例


はじめに

今回はアクター間の相対計算のお話です。
相対位置とは簡単に言うと自分から見た相手がどの位置にいるかということです。
対義語の絶対位置現実世界での経度緯度。UE上ではGetWorldLocationに相当します。

この手の計算は特にVR開発で重要なテクニックです。
机の引き出しや、銃のスライドなど。個別で触れるけど、基本的にくっついていてほしいものを操作するとき
この相対計算を知っているかどうかでだいぶ作業が楽になります。
ぜひ相対計算をマスターしてパーツまみれのVRギミックを作りまくりましょう!

ChildActorじゃダメなんですか。。?

UE4やUE5にはコンポーネントとしてアクターを所有できるChildActorコンポーネントが存在します。

ChildActorで設定されたアクターの位置はGetRelativeLocationなどで相対位置を取得することができます。

これでいいじゃん!!

ダメとは言いませんが絶対やめたほうがいいです。
理由は以下の通りです。

・ アクター自体を所持しているため参照や可読性が煩雑化する。
・ 複数の対象がいるときChildActorを複数持たせなければならない。
・ ChildActorはバグりやすい!!(4.26.2現在)レベル上に配置したChildActorの増殖バグ、変更が適応されないなどなど...

これらのことからChildActorはあくまで武器や見た目などの、所有されるだけの存在で基本的にChildActor側で移動などを行う場合は使わないほうがよいです。

そこでコンポーネントとして持たせずにアクター間の相対計算ができるInverseTransformの出番です。

InverseTransformで実装してみよう!

解説に都合がよいサードパーソンテンプレートで説明します。

解説用にStaticMeshActorを親としたBP_Cube_AとBP_Cube_Bを作成しました。
どちらもテキストコンポーネントを追加しただけのアクターです。

今回はAを基準としたBの相対位置を取得してみます。
エディタでも確認できるようにConstructionScriptに実装します。
BP_Cube_AのConstructionScriptに画像のようにノードを配置します。
変数BP_Cube_Bは型がBP_Cube_Bでインスタンス編集可能にチェックを入れておきましょう。

また、レベル上のBP_CubeAを選択しBP_Cube_Bを選んでおきましょう。

この状態でBP_CubeAを移動してみましょう。
移動するたびにBP_CubeAとB間の相対距離の座標が出力されているはずです。
またどちらも選択した状態で移動してみましょう。
相対位置なのでほぼ変化がないはずです。

応用:プレイヤーがどっちから入ったかの判定

事前準備

少しマップを改変してこのような形を作ってみました。

一本道の廊下があって間にBP_TriggerGateが配置されています。
このBP_TriggerGateはプレイヤーのみに反応し、プレイヤーがどちらから来たかを判定しようとしています。

BP_TriggerGateの中身

メッシュはエンジン付属の1M_Cubeを使用していますが、
デフォルト設定ではコリジョンがありません。アセットのビューからコリジョン->Box単純化コリジョンを作成しましょう。

当たり判定のログを出してキャラクターが触れたらログが出るかを確認します。

実装開始


画像のようにノードを組みます。
プレイヤーとこの壁との相対位置を比較しそれがプラスかマイナスかで判定を行っています。

さいごに

相対位置や相対回転が求められる。InverseTransformノード。
引き出しや銃のスライドなどインタラクティブなシステムを実装する際に非常に使い勝手の良いものとなっています。
特にVRゲームなどにおいてはその真価を特に発揮することができます。
数学的な説明を排除して使い方のみ解説しましたが、
内部処理を知りたい方は「逆行列 座標変換」などで検索してみるとより理解が深まるかと思います。

今後UE4や5向けの記事をかいていく予定です。
皆さんの応援が投稿のモチベーションになりますので、
コメントやSNS等で共有などしていただけるとありがたいです。
それではよきゲーム開発を。