UnityEngine.XR の InputFeatureUsage を利用してVR空間内で移動処理を行う【UnityEngine.XR】

Oculus Integration の OVRInput を利用せずに,移動処理を行いたいのが関心です.

Oculus Integration の場合

Oculus Integration なら OVRCameraRig や OVRPlayerController Prefab を利用すればすぐに移動処理が出来ます.

kan-kikuchi.hatenablog.com

XR Interaction Toolkit の場合

XR Interaction Toolkit (本記事執筆時点)には移動処理のスクリプトが最初から搭載されていません.
よって,自作する必要があります.

XR Interaction Toolkit 0.10 以上から移動処理のスクリプトが新しく追加されました.

xrdnk.hateblo.jp

環境

こちらの記事と同じ環境です.

xrdnk.hateblo.jp

サンプルスクリプト

UnityEngine.XR を利用して,移動処理のサンプルスクリプトを作成しました.
こちらをXR Rigにアタッチすればいいかもしれません.

using UnityEngine;
using UnityEngine.XR;

public class XRPlayerController : MonoBehaviour
{
    [SerializeField] private float _speed = 2.0f;
    [SerializeField] private XRNode _controllerNode = XRNode.LeftHand;

    private InputDevice _controller;

    void Start()
    {
        GetInputDevice();
    }

    void Update()
    {
        UpdateMovement();
    }

    private void GetInputDevice()
    {
        // XRNode から デバイスのインスタンスを取得
        _controller = InputDevices.GetDeviceAtXRNode(_controllerNode);
    }

    private void UpdateMovement()
    {
        // 入力タイプ primary2DAxis の取得
        InputFeatureUsage<Vector2> primary2DVector = CommonUsages.primary2DAxis;

        // primary2DVector のデータ格納用の変数
        Vector2 primary2DValue;

        if (_controller.TryGetFeatureValue(primary2DVector, out primary2DValue) && primary2DValue != Vector2.zero)
        {
            // 前後方向 2軸では xの移動量 -> 3軸では xの移動量になる
            // 左右方向 2軸では yの移動量 -> 3軸では zの移動量になる
            float xAxis = primary2DValue.x * _speed * Time.deltaTime;
            float zAxis = primary2DValue.y * _speed * Time.deltaTime;

            // ローカル空間からワールド空間へ方向ベクトルを変換し,移動量をかけたものを加える
            transform.position += transform.TransformDirection(Vector3.right) * xAxis;
            transform.position += transform.TransformDirection(Vector3.forward) * zAxis;
        }
    }
}

GetDeviceAtXRNode

XRNode から InputDevices.GetDeviceAtXRNode で対応するデバイスインスタンスの取得を行っています.

InputFeatureUsage

ドキュメントの説明ではInputFeatureUsage は C#構造体で,
任意プラットフォームのユーザ入力にアクセスするための標準の一軍の物理的デバイス制御を定義しています.(?)
わかりやすい例としては,primary2DAxis,trigger,grip,primaryButtonなどでしょうか.
入力タイプと考えてよいかもしれません.

各 InputFeatureUsage の定義については,XR.Input.CommonUsages を参照すると書かれています.

docs.unity3d.com

InputFeatureUsage と 一般的なXRシステムのコントローラの対応表はこのようになってます.
今回はジョイスティックの値を取得したいので,入力タイプ primary2DAxis を取得しています.

f:id:xrdnk:20210127232905p:plain

docs.unity3d.com

TryGetFeatureValue

バイスのprimary2DVector の値を取得する際に TryGetFeatureValue を利用しています.out 修飾子で参照渡しをしています.
後は2軸の値を3軸へ対応させて,さらにローカル空間からワールド空間へ変換すれば完了です.

実機確認

youtu.be

無事に移動処理を行うことができました.
XR Interaction Toolkit にも Oculus Integration にも依存してないので汎用的に使えるかも.