Unreal EngineにおけるHMDの視点を操作する方法~その2~
本投稿は,Unreal Engine(UE)において,HMD使用時の視点(カメラ)を制御する方法に関する投稿です.
「HMDを用いた場合のカメラの親子構造」に関しては,過去の投稿[1]で説明しています.
使用しているUEのバージョンは4.26.2です.
目次
1. 「車両の運転者視点」などに向けた課題
過去の投稿[1]では,HMDを装着した頭の移動や回転だけでなく,カメラ アクタのRootComponentのLocationやRotationの値を変更することで,HMDに出力される視点の移動や回転が可能になる手法を説明した.
しかしこの手法では,例えば「車両の運転者視点」などの用途では問題が生じる.まず「車両の運転者視点」では下記のような要素が必要になる.
- 車両の旋回に合わせて,運転者の身体ごと視点も回転させる必要がある
- 車両の旋回とは独立して,運転者が首を左右に振る動き(=HMDを装着した頭部の動き)によって,視点も移動や回転できる必要がある
上記を実装する手段として,下記の2つが考えられるが,それぞれ利点と欠点がある.
- 車両のBPクラスに,カメラをコンポーネントとして追加した場合
- 利点:車両の移動や旋回に追従してカメラの移動や回転が自動で行われる
- 欠点:車両とカメラのDefaultSceneRootが同一であり,カメラだけ回転させることができない(つまり上記「2つ目の要素」ができない)
- 車両のBPクラスとは別に,カメラアクタを用いた場合
- 利点:HMDに追従した移動と回転も,カメラ アクタのRootComponentの数値を書き換える手法による移動や回転も,可能である
- 欠点:車両の移動量や回転量に合わせて,カメラ アクタを移動・回転させる必要がある.
特に回転に関し,上記「1つ目の要素」車両の旋回において,車両の回転軸とカメラ アクタの回転軸が異なる問題がある.これは,車両の回転量をそのままカメラのRotationに加算しても,車両が(車両の回転軸で)旋回したときに合わせて乗車している身体の向きが(車両の回転軸で)回転する視界の変化を再現できない問題に通ずる(図1~2).
本投稿では「車両のBPクラスに,カメラをコンポーネントとして追加する」手法を用いつつ,欠点であるカメラだけを回転させる手法を,第2章で説明する.
2. 解決方法
まずはじめに,車両のBPクラスのコンポーネントに,カメラを追加する.追加の仕方は,コンポーネントタブの「コンポーネントを追加」から,カメラを追加できる.
次に,追加したカメラ コンポーネントに対し「詳細タブ>カメラセッティング>Lock to Hmd」のチェックを外す.この機能は,HMDを装着した頭部の移動量や回転量に合わせて,UE内のカメラを拘束する機能である.
この機能のチェックを外すと拘束が無くなり,図3のようにHMDを装着してどの方向を向いても表示される映像は同じままとなり,頭部の位置や向きと映像が一致しなくなる.
しかし拘束が無くなることで,BPクラスのコンポーネント化したカメラ コンポーネントのLocationやRotationに対する値の変更内容が,HMDに出力される映像に反映されるようになる.
最後に,「Lock to Hmd」のチェックを外した状態でも,HMDの移動量や回転量も反映させるよう,BPで制御する.制御例を図4および表1に示す.
処理内容の説明をする.Locationにおいては,カメラ コンポーネントのLocationに,カメラ コンポーネントのLocationとHMDのPositionとの加算値を代入する.ここで,ただHMDのPositionを加算してしまうと,HMDの初期位置から僅かでも頭部の位置がずれた状態で居ると,そのずれの分だけ毎フレーム加算されてしまい,結果として「静止している(つもり)状態のはずが,勝手にカメラが移動し続けてしまう」現象が起きる.そのため,1フレーム前と現フレームとのPositionの差分を求める.そしてのそのPositionの差分とカメラ コンポーネントのLocationとの加算値を,カメラ コンポーネントのLocationに代入する.この処理により,車両の移動とは独立した運転者(=HMD装着者)の頭部の移動が反映される.
Rotationにおいては,カメラ コンポーネントのRotationに,車両のRootComponentのRotatioとHMDのRotationとの加算値を代入する.この処理により,車両の旋回とは独立した運転者(=HMD装着者)が首を振る動きが反映される.
変数/関数名 |
内容 |
carObject変数 | 「車両のBPクラス」型のオブジェクト |
driverViewCamera変数 | 車両のBPクラスに追加したカメラ コンポーネント |
getWorldLocation関数 | 任意のSceneComponentオブジェクトにおける,ワールド座標系のLocationを取得する |
getOrientationandPosition関数 | HMDの現在の位置(Position=Location)と向き(Rotation)を取得する |
oldHmdPosition変数 | 1フレーム前のHMDのPosition値を格納する変数 |
getWorldRotation関数 | 任意のSceneComponentオブジェクトにおける,ワールド座標系のRotationを取得する |
combineRotators関数 | 任意の2つのRotationを加算する |
参考文献
- word in the world, Unreal EngineにおけるHMDの視点を操作する方法, https://word-in-the-world.com/2021/12/12/ue-hmd-view/, (参照 2023-1-31).