LoginSignup
22
17

More than 3 years have passed since last update.

UnityでOculus Questのハンドトラッキングを使ってみる(タッチ&ピンチ)

Last updated at Posted at 2020-01-15

Oculus Quest のハンドトラッキングで下記を試します。

  • 手の表示
  • キューブをタッチして色を変える
  • ピンチ操作でキューブの色を変える

環境

Unity 2019.2.17f1

事前準備

  • UnityでQuest用のビルドができること
  • Oculus Integration Assetsを追加していること

Scene作成

Hierarchy
Oculus > VR > Prefabs > OVRCameraRig を追加
(最初にあったMainCameraは削除しておく)

Inspector
OVR Manager (script) > Input > Hand Tracking Support → [Controllers and Hands]
OVR Manager (script) > Tracking > Tracking Origin Type → [Floor Level]

image.png

手を追加

Hierarchy
Oculus > VR > Prefabs > OVRHandPrefab を LeftHandAnchor と RightHandAnchor の下に追加

image.png

Inspector
OVRHand、OVRSkeleton、OVRMesh の各 HandType に Hand Left または Hand Right を選択
OVRSkeleton の Enable Physics Capsules にチェック

image.png

スケルトン表示にする場合

OVRHandPrefab の OVR Skeleton Renderer にチェック

カスタムマテリアルにする場合

OVRHandPrefab の Skinned Mesh Renderer で Materials > Element0 を好きなマテリアルに変える

ビルド確認

ハンドトラッキングされた手が表示されていればOK

v1nh4-ulwxs.gif

左がスケルトン、右がカスタムマテリアル

com.qvtecCompany.OculusQuestHandTracking-20200115-234849.jpg

衝突イベント

キューブをタッチして色を変えてみます。

Hierarchy
Cube を追加して位置と大きさを適当に調整(size:0.2, position: 0,0.5,1)

Inspector
Box Collider の Is Triggerをチェック

ChangeColor.csスクリプトを作成し、Cube に追加

ChangeColor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CubeTouch : MonoBehaviour
{
    private Renderer renderer;

    void Start()
    {
        renderer = this.gameObject.GetComponent<Renderer>();
    }

    private void OnTriggerEnter(Collider collider)
    {
        if (collider.gameObject.name == "Hand_Index3_CapsuleCollider")
        {
            renderer.material.color = Color.red;
        }
    }

    private void OnTriggerExit(Collider collider)
    {
        if (collider.gameObject.name == "Hand_Index3_CapsuleCollider")
        {
            renderer.material.color = Color.white;
        }
    }
}

ヒットしたら赤、外れたら白にマテリアルを更新しています。
colliderの名前は Hand_XXX_CapsuleCollider だったので、BoneIdから判定したいボーンを指定します。

OVRPlugin.cs
public enum BoneId
{
  Invalid                 = -1,

  Hand_Start              = 0,
  Hand_WristRoot          = Hand_Start + 0, // root frame of the hand, where the wrist is located
  Hand_ForearmStub        = Hand_Start + 1, // frame for user's forearm
  Hand_Thumb0             = Hand_Start + 2, // thumb trapezium bone
  Hand_Thumb1             = Hand_Start + 3, // thumb metacarpal bone
  Hand_Thumb2             = Hand_Start + 4, // thumb proximal phalange bone
  Hand_Thumb3             = Hand_Start + 5, // thumb distal phalange bone
  Hand_Index1             = Hand_Start + 6, // index proximal phalange bone
  Hand_Index2             = Hand_Start + 7, // index intermediate phalange bone
  Hand_Index3             = Hand_Start + 8, // index distal phalange bone
  Hand_Middle1            = Hand_Start + 9, // middle proximal phalange bone
  Hand_Middle2            = Hand_Start + 10, // middle intermediate phalange bone
  Hand_Middle3            = Hand_Start + 11, // middle distal phalange bone
  Hand_Ring1              = Hand_Start + 12, // ring proximal phalange bone
  Hand_Ring2              = Hand_Start + 13, // ring intermediate phalange bone
  Hand_Ring3              = Hand_Start + 14, // ring distal phalange bone
  Hand_Pinky0             = Hand_Start + 15, // pinky metacarpal bone
  Hand_Pinky1             = Hand_Start + 16, // pinky proximal phalange bone
  Hand_Pinky2             = Hand_Start + 17, // pinky intermediate phalange bone
  Hand_Pinky3             = Hand_Start + 18, // pinky distal phalange bone
  Hand_MaxSkinnable       = Hand_Start + 19,
  // Bone tips are position only. They are not used for skinning but are useful for hit-testing.
  // NOTE: Hand_ThumbTip == Hand_MaxSkinnable since the extended tips need to be contiguous
  Hand_ThumbTip           = Hand_Start + Hand_MaxSkinnable + 0, // tip of the thumb
  Hand_IndexTip           = Hand_Start + Hand_MaxSkinnable + 1, // tip of the index finger
  Hand_MiddleTip          = Hand_Start + Hand_MaxSkinnable + 2, // tip of the middle finger
  Hand_RingTip            = Hand_Start + Hand_MaxSkinnable + 3, // tip of the ring finger
  Hand_PinkyTip           = Hand_Start + Hand_MaxSkinnable + 4, // tip of the pinky
  Hand_End                = Hand_Start + Hand_MaxSkinnable + 5,

  // add new bones here

  Max = Hand_End + 0,
}

https://en.wikipedia.org/wiki/Phalanx_bone#/media/File:Scheme_human_hand_bones-en.svg
0から3にかけて指先になる

ピンチ操作

ピンチ操作でキューブの色を変えてみます。

手の表示で追加した OVRHandPrefab に MyHand.cs スクリプトを追加

MyHand.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyHand : MonoBehaviour
{    
    private OVRHand hand;
    private Renderer renderer;

    void Start()
    {
        renderer = GameObject.Find("Cube").GetComponent<Renderer>();
        hand = this.gameObject.GetComponent<OVRHand>();
    }

    void Update()
    {
        if (hand.GetFingerIsPinching(OVRHand.HandFinger.Middle))
        {
            renderer.material.color = Color.blue;
        }
        else if (material.color == Color.blue)
        {
            renderer.material.color = Color.white;
        }
    }
}

hand.GetFingerIsPinching でピンチしているかどうかを取得できます。
OVRHand.HandFinger.Middle をIndexやRingにするとピンチする指の指定ができます。
中指と親指をくっつけると青、離すと白にマテリアルを更新しています。

完成

ちゃんと中指以外は色が変わらない!
両手使える!

gumhj-05rps.gif

公式サイト
https://developer.oculus.com/documentation/unity/latest/concepts/unity-handtracking/

さいごに

薬指と小指は重なってしまって誤動作しやすい。
何か操作に使う場合は中指が良さそう。(人差し指は選択)
次は SDK の SampleFramework を使った方法も試してみる。

UnityでOculus IntegrationのSampleFrameworkを使ってOculus Questのハンドトラッキングを試す

22
17
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
22
17