0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

UnityVR入力スターターキット

Last updated at Posted at 2021-07-25

準備

UnityVRテンプレートから超簡単にワールド内を移動できるようになります。
検証エディタ:Unity2021.1
UnityHubで新しいプロジェクトを作る際にテンプレート「VR」を選択して作成。
プロジェクト設定のXRPluginManagementでOculusをチェック
以下のスクリプトを適当にアセットフォルダに作成します。

VR_Input.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
public class VR_Input : MonoBehaviour
{
    public enum InputVRBool { Primary, Secondary, Trigger, Grip, Menu, PrimaryAxis };
    public enum InputVRFloat { Trigger, Grip };
    public static bool GetPresseButton(XRNode node, InputVRBool inputVRBool)
    {
        bool value = false;
        var inputdevice = new List<InputDevice>();
        InputDevices.GetDevicesAtXRNode(node, inputdevice);
        if (0 < inputdevice.Count)
        {
            foreach (var device in inputdevice)
            {
                switch (inputVRBool)
                {
                    case InputVRBool.Trigger: device.TryGetFeatureValue(CommonUsages.triggerButton, out value); break;
                    case InputVRBool.Grip: device.TryGetFeatureValue(CommonUsages.gripButton, out value); break;
                    case InputVRBool.Primary: device.TryGetFeatureValue(CommonUsages.primaryButton, out value); break;
                    case InputVRBool.Secondary: device.TryGetFeatureValue(CommonUsages.secondaryButton, out value); break;
                    case InputVRBool.PrimaryAxis: device.TryGetFeatureValue(CommonUsages.primary2DAxisClick, out value); break; 
                    case InputVRBool.Menu:
                        if (node == XRNode.LeftHand)
                        {
                            device.TryGetFeatureValue(CommonUsages.menuButton, out value);
                        }
                        break;
                }
            }
        }
        return value;
    }
    public static float GetAxis1D(XRNode node, InputVRFloat inputVRFloat)
    {
        float value = 0;
        var inputdevice = new List<InputDevice>();
        InputDevices.GetDevicesAtXRNode(node, inputdevice);
        if (0 < inputdevice.Count)
        {
            foreach (var device in inputdevice)
            {
                switch (inputVRFloat)
                {
                    case InputVRFloat.Trigger: device.TryGetFeatureValue(CommonUsages.trigger, out value); break;
                    case InputVRFloat.Grip: device.TryGetFeatureValue(CommonUsages.grip, out value); break;
                }
            }
        }
        return value;
    }
    public static Vector2 GetAxis2D(XRNode node)
    {
        Vector2 value = Vector2.zero;
        var inputdevice = new List<InputDevice>();
        InputDevices.GetDevicesAtXRNode(node, inputdevice);
        if (0 < inputdevice.Count)
        {
            foreach (var device in inputdevice)
            {
                device.TryGetFeatureValue(CommonUsages.primary2DAxis, out value);
            }
        }
        return value;
    }
    public static void Recenter()
    {
        var inputdevice = new List<InputDevice>();
        InputDevices.GetDevicesAtXRNode(XRNode.CenterEye, inputdevice);
        if (0 < inputdevice.Count)
        {
            foreach (var device in inputdevice)
            {
                device.subsystem.TryRecenter();
            }
        }
    } 
}

次に、以下のスクリプトを作成、サンプルシーンにある「XRRig」というオブジェクトにくっつけます。

VR_BasicController.cs
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class VR_BasicController : MonoBehaviour
{
    private CharacterController cc;
    [SerializeField] private float speed = 2;
    [SerializeField] private int angle = 30;
    private bool RT, LT;
    private Vector2 stickL;
    private Vector2 stickR;
    private float gravity = 20;//9.81f;  
    void Start()
    {
        cc = GetComponent<CharacterController>();
        VR_Input.Recenter();
    }
    void Update()
    {
        stickL = VR_Input.GetAxis2D(UnityEngine.XR.XRNode.LeftHand);
        stickR = VR_Input.GetAxis2D(UnityEngine.XR.XRNode.RightHand);
        Move();
        Rotate();
        if (VR_Input.GetPresseButton(UnityEngine.XR.XRNode.RightHand, VR_Input.InputVRBool.PrimaryAxis))
        {
            VR_Input.Recenter();
        }
    }
    void Move()
    {
        cc.enabled = true;
        Vector3 direction = new Vector3(stickL.x, 0, stickL.y);
        Vector3 velocity = direction * speed;
        velocity.y -= gravity;
        velocity = transform.TransformDirection(velocity);
        cc.Move(velocity * Time.deltaTime);
    }
    void Rotate()
    {
        if (stickR.x < -0.25f && !LT)
        {
            LT = true;
            transform.Rotate(0, -angle, 0);
        }
        if (0.25f < stickR.x && !RT)
        {
            RT = true;
            transform.Rotate(0, angle, 0);
        }
        if (stickR.x == 0)
        {
            LT = false; RT = false;
        }
    }
}

使い方

左スティックで移動
右スティックで回転
右スティック押し込みでリセンタリング(デバッグ時のみ)

余談

Oculus+UnityでVRやりたい場合はアセットストアから「Oculus Integration」をインポートすれば大体のことはできる。
が、そんなに機能要らない。。もっと簡単にスクリプトちょっとくっつけるだけでワールドを歩き回りたい!
と思っていたらUnityがVRテンプレートを提供してくれてたので使わせてもらいました。入力関連はどんどんアップデートしてくれているので、
今後さらにシンプルに使えるようになれたらいいね。Unityさんマジ最高です。

参考

[Unityマニュアル:Unity の XR 入力] (https://docs.unity3d.com/ja/current/Manual/xr_input.html)

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?