XR Handsパッケージ 1.2.1について
XR Handsのドキュメントが英語なので、メモとして読んだポイントを列挙。
この先Vision Proがでてきたり、ハンドトラッキングを使う機会はあるはずなので学習してます。
XR HandsパッケージはハンドトラッキングのAPIを提供するけど、機能自体は実装していない。ターゲットプラットフォームでハンドトラッキングを利用するには、XRHandSubsystemにハンドトラッキングのデータを渡してくれるプラットフォームに適したplug-in パッケージの追加が必要です。
※今のところOpenXR packageが唯一のハンドトラッキングをサポートするplug-inです。
他のplug-inのハンドトラッキングのサポート状況については各パッケージの情報を参照すること。
XR Hands 1.2.1はUnity 2021.3以降に対応しているけど、Unity 2023.1以前だとPackage ManagerのUnity Registryから入れるのではなくて、Add package by nameから com.unity.xr.hands を直接指定する。
シーンを作成するときはCreate > XR > XR Originで追加する、とチュートリアルには書いてあるけど、XR Interaction Hands SetupのプレハブがあるのでそれをヒエラルキーにつっこんでもOKだった。
Hand tracking data
XR Handパッケージを使ってアクセスできるデータについて。
-
Hand data model:ユーザーの手の手首から上の関節位置26個所の位置、向き、動きを提供する。親指は中間骨がないので、他の指よりも1か所少ない。
hand APIが返す情報は空間と相対的な情報で、距離の単位はm。
XRHand.rootPoseは手の位置情報、XRHandJointは関節の情報、XRHandDeviceはつまんだり、握ったりの情報。これらがあれば手の軌道とかは取れそうです。
-
Access hand data:XRHandSubsystemをサブスクライブしているXRHandTrackingEventsを利用してPose Updated、Joints Updated、Tracking Acquiredなどのタイミングで処理を実行させることができる。実際にはこちらの方でHand data modelの情報を取得する感じ。
-
Hand visuals:手のデータは手首を親として指先までの階層構造になっている。
- Wrist:手首
- Palm:手のひら
- Metacarpal:手首から指の間の骨
- Proximal:こぶしの部分
- Intermediate:第2関節
- Distral:第一関節
- Tip:指先
※Thumbが親指、Indexが人差し指、Middleが中指、Ringが薬指、Littleが小指
OpenXR機能
- Hand Tracking:OpenXR向けのHand tracking dataを利用するための機能
- Meta Aim Hand:OpenXRで利用するためのMeta Aim Hand extensionを実装
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Hands;
public class HandsExample : MonoBehaviour
{
XRHandSubsystem m_HandSubsystem;
void Start()
{
var handSubsystems = new List<XRHandSubsystem>();
SubsystemManager.GetSubsystems(handSubsystems);
for (var i = 0; i < handSubsystems.Count; ++i)
{
var handSubsystem = handSubsystems[i];
if (handSubsystem.running)
{
m_HandSubsystem = handSubsystem;
break;
}
}
if (m_HandSubsystem != null)
m_HandSubsystem.updatedHands += OnUpdatedHands;
}
void OnUpdatedHands(XRHandSubsystem subsystem,
XRHandSubsystem.UpdateSuccessFlags updateSuccessFlags,
XRHandSubsystem.UpdateType updateType)
{
switch (updateType)
{
case XRHandSubsystem.UpdateType.Dynamic:
// Update game logic that uses hand data
break;
case XRHandSubsystem.UpdateType.BeforeRender:
// Update visual objects that use hand data
break;
}
}
}
Discussion