OVRSkelton を利用すると、片手で24箇所の位置(以下の図の球の箇所)が取得できます。
前提
Unity 2019.3.0f3
Oculus Integration 12.0
OVRSkelton.cs について
Oculus Integration でハンドトラッキングする時に追加する、OVRHandTrackingPrefab に最初から設定されているプログラムです。このプログラムが持っている Bones(OVRBoneというクラスのリスト)と、各位置を指し示す BoneId を利用することで、指の関節などの情報を取得します。
この方の記事がわかりやすいです。(この記事を書く前に知りたかった・・・)
https://qiita.com/divideby_zero/items/4949fadb2c60f810b3aa
部位取得の概要
部位 | 取得箇所数 | 指定方法の概要 |
---|---|---|
親指 | 5 | 付け根側から 0, 1, 2, 3, tip |
人差し指 | 4 | 付け根側から 1, 2, 3, tip |
中指 | 4 | 付け根側から 1, 2, 3, tip |
薬指 | 4 | 付け根側から 1, 2, 3, tip |
小指 | 5 | 付け根側から 0, 1, 2, 3, tip |
手首 | 2 | WristRoot, ForearmStub |
部位を指定するBoneIdの詳細
(上の図を見た方が解りやすい)
BoneId | 部位の説明 |
---|---|
Hand_WristRoot | 手の付け根 |
Hand_ForearmStub | 腕でも手に近いところ |
Hand_Thumb0 | 親指の第3関節から手首側に小さな骨があり、その付け根 |
Hand_Thumb1 | 親指の第3関節 |
Hand_Thumb2 | 親指の第2関節 |
Hand_Thumb3 | 親指の第1関節 |
Hand_ThumbTip | 親指の先端 |
Hand_Index1 | 人差し指の第3関節 |
Hand_Index2 | 人差し指の第2関節 |
Hand_Index3 | 人差し指の第1関節 |
Hand_IndexTip | 人差し指の先端 |
Hand_Middle1 | 中指の第3関節 |
Hand_Middle2 | 中指の第2関節 |
Hand_Middle3 | 中指の第1関節 |
Hand_MiddleTip | 中指の先端 |
Hand_Ring1 | 薬指の第3関節 |
Hand_Ring2 | 薬指の第2関節 |
Hand_Ring3 | 薬指の第1関節 |
Hand_RingTip | 薬指の先端 |
Hand_Pinky0 | 小指の第3関節から手首側に伸びている骨の付け根 |
Hand_Pinky1 | 小指の第3関節 |
Hand_Pinky2 | 小指の第2関節 |
Hand_Pinky3 | 小指の第1関節 |
Hand_PinkyTip | 小指の先端 |
外部から値を取得するプログラム
サンプル
using UnityEngine;
public class Hand : MonoBehaviour
{
[SerializeField] private OVRSkeleton skeleton;
[SerializeField] private Transform thumb0;
[SerializeField] private Transform thumb1;
[SerializeField] private Transform thumb2;
[SerializeField] private Transform thumb3;
[SerializeField] private Transform thumbTip;
[SerializeField] private Transform index1;
[SerializeField] private Transform index2;
[SerializeField] private Transform index3;
[SerializeField] private Transform indexTip;
[SerializeField] private Transform middle1;
[SerializeField] private Transform middle2;
[SerializeField] private Transform middle3;
[SerializeField] private Transform middleTip;
[SerializeField] private Transform ring1;
[SerializeField] private Transform ring2;
[SerializeField] private Transform ring3;
[SerializeField] private Transform ringTip;
[SerializeField] private Transform pinky0;
[SerializeField] private Transform pinky1;
[SerializeField] private Transform pinky2;
[SerializeField] private Transform pinky3;
[SerializeField] private Transform pinkyTip;
[SerializeField] private Transform start;
[SerializeField] private Transform wristRoot;
[SerializeField] private Transform forearmStub;
[SerializeField] private Transform maxSkinnable;
[SerializeField] private Transform end;
void Update()
{
thumb0.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Thumb0].Transform.position;
thumb1.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Thumb1].Transform.position;
thumb2.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Thumb2].Transform.position;
thumb3.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Thumb3].Transform.position;
thumbTip.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_ThumbTip].Transform.position;
index1.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Index1].Transform.position;
index2.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Index2].Transform.position;
index3.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Index3].Transform.position;
indexTip.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_IndexTip].Transform.position;
middle1.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Middle1].Transform.position;
middle2.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Middle2].Transform.position;
middle3.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Middle3].Transform.position;
middleTip.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_MiddleTip].Transform.position;
ring1.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Ring1].Transform.position;
ring2.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Ring2].Transform.position;
ring3.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Ring3].Transform.position;
ringTip.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_RingTip].Transform.position;
pinky0.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Pinky0].Transform.position;
pinky1.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Pinky1].Transform.position;
pinky2.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Pinky2].Transform.position;
pinky3.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Pinky3].Transform.position;
pinkyTip.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_PinkyTip].Transform.position;
wristRoot.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_WristRoot].Transform.position;
forearmStub.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_ForearmStub].Transform.position;
start.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Start].Transform.position;
// maxSkinnable.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_MaxSkinnable].Transform.position;
end.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_End].Transform.position;
}
}
補足
- Hand_Start、Hand_MaxSkinnable、Hand_End はBoneIdとしては使用されておらず、プログラムを読む限り、Enum の中で値を仕切るために使用されているように見える。
- このプログラムを実行しても、Hand_Start、Hand_Endの球は表示されることがない。
- Hand_MaxSkinnable をコメントアウトしているのは、親指の先端と同じ値が設定されているため。コメントを外すと親指の先端箇所に Hand_MaxSkinnable の球が表示される。
- OVRSkelton の BoneId の enum の中に、
// add new bones here
とコメントがあることから、これからまだ何かしらの値を追加していく想定見て取れる。それを見越しての、Hand_Start などなのだと思われる。