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]
手を追加
Hierarchy
Oculus > VR > Prefabs > OVRHandPrefab を LeftHandAnchor と RightHandAnchor の下に追加
Inspector
OVRHand、OVRSkeleton、OVRMesh の各 HandType に Hand Left または Hand Right を選択
OVRSkeleton の Enable Physics Capsules にチェック
スケルトン表示にする場合
OVRHandPrefab の OVR Skeleton Renderer にチェック
カスタムマテリアルにする場合
OVRHandPrefab の Skinned Mesh Renderer で Materials > Element0 を好きなマテリアルに変える
ビルド確認
ハンドトラッキングされた手が表示されていればOK
左がスケルトン、右がカスタムマテリアル
衝突イベント
キューブをタッチして色を変えてみます。
Hierarchy
Cube を追加して位置と大きさを適当に調整(size:0.2, position: 0,0.5,1)
Inspector
Box Collider の Is Triggerをチェック
ChangeColor.csスクリプトを作成し、Cube に追加
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から判定したいボーンを指定します。
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 スクリプトを追加
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にするとピンチする指の指定ができます。
中指と親指をくっつけると青、離すと白にマテリアルを更新しています。
完成
ちゃんと中指以外は色が変わらない!
両手使える!
公式サイト
https://developer.oculus.com/documentation/unity/latest/concepts/unity-handtracking/
さいごに
薬指と小指は重なってしまって誤動作しやすい。
何か操作に使う場合は中指が良さそう。(人差し指は選択)
次は SDK の SampleFramework を使った方法も試してみる。
→ UnityでOculus IntegrationのSampleFrameworkを使ってOculus Questのハンドトラッキングを試す