Unreal での手の追跡
- [アーティクル]
-
-
ハンド トラッキング システムでは、人の手のひらと指が入力として使用されます。 すべての指の位置と回転、手のひら全体、手のジェスチャに関するデータを使用できます。 Unreal 4.26 以降、ハンド トラッキングは Unreal HeadMountedDisplay プラグインに基づいており、すべての XR プラットフォームとデバイスで共通の API が使用されます。 機能は、Windows Mixed Reality と OpenXR のどちらのシステムでも同じです。
手のポーズ
手のポーズを使用すると、ユーザーの手と指を入力として追跡して使用できます。これには、ブループリントと C++ の両方でアクセスできます。 Unreal API によってデータが座標系として送信され、ティックは Unreal Engine と同期されます。


階層は EHandKeypoint
列挙型によって記述されます。

このデータはすべて、[モーション コントローラー データの取得] 関数を使用してユーザーの手から取得できます。 その関数からは XRMotionControllerData 構造体が返されます。 次に、XRMotionControllerData 構造体を解析して手の関節の位置を取得し、各関節の位置にデバッグ座標系を描画するブループリント スクリプトのサンプルを示します。
![チャネル関数によってライン トレースに接続された [視線データの取得] 関数のブルーポイント](images/unreal-hand-tracking-img-03.png)
構造体が有効であるかどうかと、それが手であるかどうかを確認することが重要です。 そうしないと、位置、回転、半径配列へのアクセスで未定義の動作が発生する可能性があります。
EWMRHandKeypoint
列挙型では、手の骨の階層を説明します。 それぞれの手のキーポイントは、ブループリントに一覧表示されています。

下に、完全な C++ 列挙型を示します。
enum class EWMRHandKeypoint : uint8
{
Palm,
Wrist,
ThumbMetacarpal,
ThumbProximal,
ThumbDistal,
ThumbTip,
IndexMetacarpal,
IndexProximal,
IndexIntermediate,
IndexDistal,
IndexTip,
MiddleMetacarpal,
MiddleProximal,
MiddleIntermediate,
MiddleDistal,
MiddleTip,
RingMetacarpal,
RingProximal,
RingIntermediate,
RingDistal,
RingTip,
LittleMetacarpal,
LittleProximal,
LittleIntermediate,
LittleDistal,
LittleTip
};
列挙型の各ケースの数値は、Windows.Perception.People.HandJointKind テーブルにあります。
ハンド トラッキングのサポート
[ハンド トラッキング > Windows Mixed Reality] から [ハンド トラッキングのサポート] を追加すると、ブループリントでハンド トラッキングを使用できます。

この関数によって、デバイスでハンド トラッキングがサポートされている場合は true
、ハンド トラッキングを利用できない場合は false
が返されます。

C++:
次を含めます WindowsMixedRealityHandTrackingFunctionLibrary.h
。
static bool UWindowsMixedRealityHandTrackingFunctionLibrary::SupportsHandTracking()
ハンド トラッキングの取得
GetHandJointTransform を使用すると、手から空間データを返すことができます。 データはフレームごとに更新されますが、フレーム内に入っている場合は、返された値がキャッシュされます。 パフォーマンス上の理由から、この関数に負荷の高いロジックを使用することはお勧めしません。

C++:
static bool UWindowsMixedRealityHandTrackingFunctionLibrary::GetHandJointTransform(EControllerHand Hand, EWMRHandKeypoint Keypoint, FTransform& OutTransform, float& OutRadius)
次に、GetHandJointTransform の関数パラメーターの詳細を示します。
- 手 – ユーザーの左手または右手。
- キーポイント – 手の骨。
- 変換 – 骨の基盤の座標と向き。 次の骨の基盤を要求して、骨端の変換データを取得できます。 特殊な先端の骨は、遠心端を示します。
- **半径 — 骨の基盤の半径。
- **戻り値 — このフレームで骨を追跡する場合は true、骨を追跡しない場合は false。
手の Live Link アニメーション
手のポーズは、Live Link プラグインを使用してアニメーションに公開されます。
Windows Mixed Reality と Live Link プラグインが有効になっている場合:
- [ウィンドウ] > [Live Link] を選択して、Live Link エディター ウィンドウを開きます。
- [ソース] を選択して、[Windows Mixed Reality ハンド トラッキングのソース] を有効にします

ソースを有効にしてアニメーション資産を開いた後、[プレビュー シーン] タブの [アニメーション] セクションを展開すると、追加のオプションが表示されます。

手のアニメーション階層は、EWMRHandKeypoint
の場合と同じです。 アニメーションのターゲットは WindowsMixedRealityHandTrackingLiveLinkRemapAsset を使用して変更できます。

エディターでサブクラス化することもできます。

ハンド メッシュ
重要
ハンド メッシュには OpenXR が必要です。
Unreal マーケットプレ―スまたは GitHub から入手可能な Microsoft OpenXR プラグインを使用する必要があります。
追跡対象ジオメトリとしてのハンド メッシュ
重要
OpenXR でハンド メッシュを追跡対象ジオメトリとして取得するには、[有効にされた追跡ジオメトリ] を使用して [ハンド メッシュの使用を設定] を呼び出す必要があります。
このモードを有効にするには、[有効にされた追跡ジオメトリ] を使用して [ハンド メッシュの使用を設定] を呼び出す必要があります。
![プレイ開始イベントが、有効にされた追跡ジオメトリ モードを使用した [ハンド メッシュの使用を設定] 関数に接続されたブループリント](images/unreal-hand-tracking-img-08.png)
Note
両方のモードを同時に有効にすることはできません。 1 つを有効にすると、もう一方は自動的に無効になります。
ハンド メッシュ データへのアクセス

ハンド メッシュ データにアクセスする前に、次のことを行う必要があります。
- ARSessionConfig 資産を選択し、[AR 設定] -> [ワールド マッピング] 設定を展開し、[追跡対象ジオメトリからメッシュ データを生成する] をオンにします。
既定のメッシュ パラメーターを次に示します。
- オクルージョンにメッシュ データを使用する
- メッシュ データの衝突を生成する
- メッシュ データのナビゲーション メッシュを生成する
- ワイヤーフレームでのメッシュ データのレンダリング – 生成されたメッシュを示すデバッグ パラメーター
これらのパラメーター値は、空間マッピング メッシュとハンド メッシュの既定値として使用されます。 任意のメッシュのブループリントまたはコードで、いつでも変更できます。
C++ API リファレンス
追跡可能なすべてのオブジェクトのハンド メッシュ値を検索するには、EEARObjectClassification
を使用します。
enum class EARObjectClassification : uint8
{
// Other types
HandMesh,
};
次のデリゲートは、ハンド メッシュを含む追跡可能なオブジェクトがシステムで検出されると呼び出されます。
class FARSupportInterface
{
public:
// Other params
DECLARE_AR_SI_DELEGATE_FUNCS(OnTrackableAdded)
DECLARE_AR_SI_DELEGATE_FUNCS(OnTrackableUpdated)
DECLARE_AR_SI_DELEGATE_FUNCS(OnTrackableRemoved)
};
デリゲート ハンドラーでは次の関数シグネチャに従う必要があります。
void UARHandMeshComponent::OnTrackableAdded(UARTrackedGeometry* Added)
メッシュ データには、UARTrackedGeometry::GetUnderlyingMesh
を使用してアクセスできます。
UMRMeshComponent* UARTrackedGeometry::GetUnderlyingMesh()
ブループリント API リファレンス
ブループリントでハンド メッシュを操作するには:
- ブループリント アクターに ARTrackableNotify コンポーネントを追加します

- [詳細] パネルに移動し、[イベント] セクションを展開します。

- イベント グラフ内の次のノードで、追加/更新/削除時の追跡対象ジオメトリを上書きします。

OpenXR でのハンド メッシュの視覚化
ハンド メッシュを視覚化する場合は、Epic の XRVisualization プラグインを Microsoft OpenXR プラグインと共に使用する方法をお勧めします。
次に、ブループリント エディターで、パラメーターとして [有効にされた XRVisualization] を使用して Microsoft OpenXR プラグインの [ハンド メッシュの使用を設定] 関数を使用する必要があります。
![プレイ開始イベントが、有効にされた XRVisualization モードを使用した [ハンド メッシュの使用を設定] 関数に接続されたブループリント](images/unreal-hand-tracking-img-05.png)
レンダリング プロセスを管理するには、XRVisualization から [モーション コントローラーのレンダリング] を使用する必要があります。
![[モーション コントローラーのデータの取得] 関数が、[モーション コントローラーのレンダリング] 関数に接続されたブループリント](images/unreal-hand-tracking-img-06.png)
結果は次のようになります。

カスタム シェーダーを使用したハンド メッシュの描画などのより複雑な操作が必要な場合は、メッシュを追跡対象ジオメトリとして取得する必要があります。
ハンド レイ
手のポーズの取得は、オブジェクトをつかんだりボタンを押したりするような密接な対話式操作で機能します。 ただし、ユーザーから離れたところにあるホログラムを操作する必要がある場合があります。 これは、C++ とブループリントの両方でポインティング デバイスとして使用できるハンド レイで実現できます。 手から遠くの地点への光線を描画し、Unreal レイ トレースを利用すると、手の届かないホログラムを選択できます。
重要
すべての関数の結果はフレームごとに変わるので、それらはすべて呼び出し可能になります。 純粋関数と非純粋関数または呼び出し可能関数の詳細については、ブループリントのユーザー ガイドで「関数」を参照してください。
ハンド レイのデータを取得するには、前のセクションの [モーション コントローラー データの取得] 関数を使用する必要があります。 返される構造体には、ハンド レイの作成に使用できる 2 つのパラメーター [目標の位置] と [目標の回転] が含まれています。 これらのパラメーターでは、肘で指示された光線を形成します。 これらを使用して、指されているホログラムを見つける必要があります。
次に、ハンド レイがウィジェットにヒットするかどうかを判断し、カスタム ヒット結果を設定する例を示します。
![[モーション コントローラーのデータの取得] 関数のブループリント](images/unreal-hand-tracking-img-04.png)
ブループリントでハンド レイを使用するには、Windows Mixed Reality HMD の下にあるアクションを検索します。

C++ でアクセスするには、呼び出し元のコード ファイルの先頭に WindowsMixedRealityFunctionLibrary.h
を含めます。
列挙型
また、ブループリントで使用できる EHMDInputControllerButtons の下の入力ケースにもアクセスできます。

C++ でアクセスするには、EHMDInputControllerButtons
列挙型クラスを使用します。
enum class EHMDInputControllerButtons : uint8
{
Select,
Grasp,
//......
};
該当する 2 つの列挙型ケースの詳細を次に示します。
- [選択] - ユーザーがトリガーした [選択] イベント。
- エアタップ、視線入力、コミットによって、または音声入力を有効にして "選択" と言うと、HoloLens 2 でトリガーされます。
- [つかむ] - ユーザーがトリガーした [つかむ] イベント。
- ホログラムでユーザーの指を閉じると HoloLens 2 でトリガーされます。
次に示す EHMDTrackingStatus
列挙型を使用して、C++ でハンド メッシュの追跡状態にアクセスできます。
enum class EHMDTrackingStatus : uint8
{
NotTracked,
//......
Tracked
};
該当する 2 つの列挙型ケースの詳細を次に示します。
- NotTracked –- 手は表示されません
- Tracked –- 手は完全に追跡されます
構造体
PointerPoseInfo 構造体では、次の手のデータに関する情報を提供できます。
- [原点] – 手の原点
- [方向] – 手の方向
- [アップ] – 手のアップ ベクトル
- [向き] – 向きのクォータニオン
- [追跡状態] – 現在の追跡状態
次に示すように、ブループリントから PointerPoseInfo 構造体にアクセスできます。

または、C++ を使用する場合:
struct FPointerPoseInfo
{
FVector Origin;
FVector Direction;
FVector Up;
FQuat Orientation;
EHMDTrackingStatus TrackingStatus;
};
関数
以下に示す関数はすべて、どのフレームでも呼び出し可能で、継続的監視を実現します。
- [ポインターのポーズ情報] では、現在のフレームでのハンド レイ方向に関する完全な情報を返します。
ブループリント:

C++:
static FPointerPoseInfo UWindowsMixedRealityFunctionLibrary::GetPointerPoseInfo(EControllerHand hand);
- [つかんだ状態] では、現在のフレームで手をつかんでいる場合に true が返されます。
ブループリント:

C++:
static bool UWindowsMixedRealityFunctionLibrary::IsGrasped(EControllerHand hand);
- [[選択] が押された状態] では、ユーザーが現在のフレームで [選択] をトリガーした場合に true が返されます。
ブループリント:
![[選択] が押された状態の BP](images/unreal/is-select-pressed-bp.png)
C++:
static bool UWindowsMixedRealityFunctionLibrary::IsSelectPressed(EControllerHand hand);
- [ボタンがクリックされた状態] では、現在のフレームでイベントまたはボタンがトリガーされた場合に true が返されます。
ブループリント:

C++:
static bool UWindowsMixedRealityFunctionLibrary::IsButtonClicked(EControllerHand hand, EHMDInputControllerButtons button);
- [コントローラーの追跡状態の取得] では、現在のフレームでの追跡状態が返されます。
ブループリント:

C++:
static EHMDTrackingStatus UWindowsMixedRealityFunctionLibrary::GetControllerTrackingStatus(EControllerHand hand);
手ぶり
HoloLens 2 では空間ジェスチャを追跡します。つまり、これらのジェスチャを入力としてキャプチャできます。 ジェスチャの追跡は、サブスクリプション モデルに基づいています。 [ジェスチャの構成] 関数を使用して、追跡するジェスチャをデバイスに指示する必要があります。ジェスチャの詳細については、HoloLens 2 の基本的な使用方法に関するドキュメントを参照してください。
Windows Mixed Reality
![プレイ開始イベントが [ジェスチャの構成] 関数に接続されたブループリント](images/unreal-hand-tracking-img-09.png)
次に、次のイベントをサブスクライブするためのコードを追加する必要があります。


OpenXR
OpenXR では、ジェスチャ イベントは入力パイプラインを使用して追跡されます。 ハンド対話を使用すると、デバイスでは長押しジェスチャを自動的に認識できますが、他は認識しません。 OpenXRMsftHandInteraction [選択] および [つかむ] マッピングという名前です。 サブスクリプションを有効にする必要はありません。次のように、[プロジェクト設定]/[エンジン]/[入力] でイベントを宣言する必要があります。

ブループリント関数は [Windows Mixed Reality 空間入力] の下にあり、C++ 関数は呼び出し元のコード ファイルに WindowsMixedRealitySpatialInputFunctionLibrary.h
を追加することで見つかります。

列挙型
ブループリント:

C++:
enum class ESpatialInputAxisGestureType : uint8
{
None = 0,
Manipulation = 1,
Navigation = 2,
NavigationRails = 3
};
機能
CaptureGestures
関数を使用してジェスチャ キャプチャを有効にしたり無効にしたりすることができます。 有効にされたジェスチャによって入力イベントが発生すると、ジェスチャ キャプチャが成功した場合は true
、エラーが発生した場合は false
が関数によって返されます。
ブループリント:

C++:
static bool UWindowsMixedRealitySpatialInputFunctionLibrary::CaptureGestures(
bool Tap = false,
bool Hold = false,
ESpatialInputAxisGestureType AxisGesture = ESpatialInputAxisGestureType::None,
bool NavigationAxisX = true,
bool NavigationAxisY = true,
bool NavigationAxisZ = true);
ブループリントと C++ で確認できる主要なイベントを次に示します。 

const FKey FSpatialInputKeys::TapGesture(TapGestureName);
const FKey FSpatialInputKeys::DoubleTapGesture(DoubleTapGestureName);
const FKey FSpatialInputKeys::HoldGesture(HoldGestureName);
const FKey FSpatialInputKeys::LeftTapGesture(LeftTapGestureName);
const FKey FSpatialInputKeys::LeftDoubleTapGesture(LeftDoubleTapGestureName);
const FKey FSpatialInputKeys::LeftHoldGesture(LeftHoldGestureName);
const FKey FSpatialInputKeys::RightTapGesture(RightTapGestureName);
const FKey FSpatialInputKeys::RightDoubleTapGesture(RightDoubleTapGestureName);
const FKey FSpatialInputKeys::RightHoldGesture(RightHoldGestureName);
const FKey FSpatialInputKeys::LeftManipulationGesture(LeftManipulationGestureName);
const FKey FSpatialInputKeys::LeftManipulationXGesture(LeftManipulationXGestureName);
const FKey FSpatialInputKeys::LeftManipulationYGesture(LeftManipulationYGestureName);
const FKey FSpatialInputKeys::LeftManipulationZGesture(LeftManipulationZGestureName);
const FKey FSpatialInputKeys::LeftNavigationGesture(LeftNavigationGestureName);
const FKey FSpatialInputKeys::LeftNavigationXGesture(LeftNavigationXGestureName);
const FKey FSpatialInputKeys::LeftNavigationYGesture(LeftNavigationYGestureName);
const FKey FSpatialInputKeys::LeftNavigationZGesture(LeftNavigationZGestureName);
const FKey FSpatialInputKeys::RightManipulationGesture(RightManipulationGestureName);
const FKey FSpatialInputKeys::RightManipulationXGesture(RightManipulationXGestureName);
const FKey FSpatialInputKeys::RightManipulationYGesture(RightManipulationYGestureName);
const FKey FSpatialInputKeys::RightManipulationZGesture(RightManipulationZGestureName);
const FKey FSpatialInputKeys::RightNavigationGesture(RightNavigationGestureName);
const FKey FSpatialInputKeys::RightNavigationXGesture(RightNavigationXGestureName);
const FKey FSpatialInputKeys::RightNavigationYGesture(RightNavigationYGestureName);
const FKey FSpatialInputKeys::RightNavigationZGesture(RightNavigationZGestureName);
次の開発チェックポイント
用意されている Unreal 開発体験に従っている場合、MRTK コア構成要素を探索している段階にいます。 ここから、次の構成要素を続けることができます。
または、Mixed Reality プラットフォームの機能と API に移動します。
いつでも Unreal 開発チェックポイントに戻ることができます。