LoginSignup
5
6

More than 3 years have passed since last update.

OculusQuest のハンドトラッキングで摘んでVR空間を移動する

Posted at

Update の中身はわずか10行程度で、こんな感じで、空間を摘んで移動できるようになります。

Moving.gif

空中も自由自在ですね。さらっとご紹介。

解説

ほんと簡単です。

まずはつまんでいる状態を検知します

こんな感じで、つまみ始めるとキューブが小さくなり、摘んだを検出するとキューブが緑色に変わるようにしました。

PinchingDetection2.gif

プログラム

using UnityEngine;

public class PinchDetection : MonoBehaviour
{
    [SerializeField] private OVRHand ovrHand;

    [SerializeField] private Transform cube;
    [SerializeField] private MeshRenderer cubeRenderer;

    [SerializeField] private Material on;  // キューブの色変更用
    [SerializeField] private Material off; // キューブの色変更用

    public bool IsPinching = false;

    void Update()
    {
        // つまみの強さを取得、0から1の間で変化し、1は完全に親指と人指し指がくっついている状態
        var strength = ovrHand.GetFingerPinchStrength(OVRHand.HandFinger.Index);
        // 5cm x つまみの強さを取得していて、消えないように 0.1cm は残るようにしています
        var scale = Mathf.Max(0.05f * (1 - strength), 0.01f);
        // 人差し指のピンチングの強さに応じて cube の scale を変更します
        cube.localScale = new Vector3(scale, scale, scale);

        // キューブが 2cm 未満になっていることを検出
        IsPinching = cube.localScale.x < 0.02f;
        // 検出したら、キューブの色を変えます
        cubeRenderer.materials = IsPinching ? new[] {on} : new[] {off};
    }
}

そして、摘んでいるときに移動できるようにします

1フレーム前の手の位置と、現在の手の位置との差分を取得して、その変化量に応じて自分自身を移動させます。

using UnityEngine;

public class PinchingMover : MonoBehaviour
{
    [SerializeField] private GameObject me;
    [SerializeField] private GameObject hand;
    [SerializeField] private PinchDetection detection; // 上のプログラム

    private float speed = 20f; // 移動スピード、適当な値です
    private Vector3 previous;

    void Update()
    {
        // 摘んでいるときは
        if (detection.IsPinching)
        {
            // 1フレーム前の手の位置と、現在の手の位置との差分を移動量のベースに、speed を積算します
            var movement = (previous - hand.transform.localPosition) * speed;
            // 自分自身を移動させます
            me.transform.position += movement;
        }

        // Update の最後で、再び自分の手の位置を設定
        previous = hand.transform.localPosition;
    }
}

注意

  • hand.transform.localPosition にしないと、自分(me)と一緒に手(hand)が動くので、ぶっ飛んで死にます。
  • previous は Start で初期化しておいた方がいいとか、細かいところは見やすさ重視で割愛しています。

Unity の設定

PinchingMover

スクリーンショット 2020-03-25 0.47.54.png

PinchingDetection

Green16, Red16 とかは適当にMaterialを作って設定してもらえれば大丈夫です。
スクリーンショット 2020-03-25 0.49.16.png

備考

  • 摘むの補足は、前に書いた OculusQeust のハンドトラッキングの摘むを試しみた を参照ください。
  • 本当は指だけで移動できるようにしたかったり、ボルダリングみたいなのを考えていたりしていく中で、デバッグ用ならこれでいいかってなった結果の産物です。
5
6
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
5
6