手のメニューを使用すると、ユーザーは頻繁に使用される関数の手で接続された UI をすばやく表示できます。 他のオブジェクトとの対話中に誤ったアクティブ化を防ぐために、ハンド メニューには、"フラット ハンドが必要" や "視線入力のアクティブ化を使用する" などのオプションが用意されています。 これらのオプションを使用して、不要なアクティブ化を防ぐことをお勧めします。
ハンド メニューの例
HandMenuExamples.unity シーンはフォルダー MRTK/Examples/Demos/HandTracking/Scenes
下にあります。 実行中のシーンでは、現在選択されているメニューの種類のみがアクティブになります。
これらのハンドメニュープレハブは、 MRTK/Examples/Common/Prefabs
フォルダーの下にあります。
HandMenu_Small_HideOnHandDropとHandMenu_Medium_HideOnHandDrop
これら 2 つの例では、単に MenuContent オブジェクトをアクティブ化および非アクティブ化して 、OnFirstHandDetected() イベントと OnLastHandLost() イベントの メニューを表示および非表示にします。
HandMenu_Large_WorldLock_On_GrabAndPull
より長い操作時間を必要とするより複雑なメニューの場合は、メニューをワールド ロックすることをお勧めします。 この例では、 OnFirstHandDetected() イベントと OnLastHandLost() イベントで MenuContent をアクティブ化および非アクティブ化するだけでなく、メニューをワールド ロックで取得してプルできます。
バックプレートの ManipulationHandler
は、それをつかんで移動可能にします。
操作開始イベントでは 、 SolverHandler.UpdateSolvers はメニューをワールド ロックするために非アクティブ化されます。 さらに、[ 閉じる] ボタン が表示され、タスクが完了したときにユーザーがメニューを閉じることができるようにします。
Manipulation Ended イベントでは 、 HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine を呼び出して、手のひらを上げて見ることでメニューを元に戻すことができます。
[閉じる ] ボタンは 、SolverHandler.UpdateSolvers を再アクティブ化し、 MenuContent を非表示にします。
HandMenu_Large_AutoWorldLock_On_HandDrop
この例は、HandMenu_Large_WorldLock_On_GrabAndPullに似ています。 唯一の違いは、メニューが手のドロップで自動的にワールドロックされることです。 この動作は、 OnLastHandLost() イベントで MenuContent を非表示にしないことによって処理されます。 取得 & プル動作は、例HandMenu_Large_WorldLock_On_GrabAndPull同じです。
スクリプト
HandConstraint
動作は、追跡対象のオブジェクトを手の制約付きコンテンツ (手の UI、メニューなど) に対して安全な領域に制限するソルバーを提供します。 安全なリージョンは、手と交差しない領域と見なされます。
HandConstraintPalmUp
と呼ばれるHandConstraint
の派生クラスも含まれており、手のひらがユーザーに向いているときにソルバー追跡オブジェクトをアクティブ化する一般的な動作を示します。
詳細なドキュメントについては、各 HandConstraint
プロパティで使用できるツール ヒントを参照してください。 いくつかのプロパティについて、以下で詳しく説明します。

セーフ ゾーン: セーフ ゾーンは、コンテンツを制限するハンドの場所を指定します。 手との重複を避け、インタラクションの品質を向上させるために、コンテンツをウルナー側に配置することをお勧めします。 安全ゾーンは、カメラのビューに直交する平面に投影された手の向きを取り、手の周囲の境界ボックスに対するレイキャストによって計算されます。 セーフ ゾーンは、
IMixedRealityHand
で動作するように定義されていますが、他のコントローラーの種類でも機能します。 各セーフ ゾーンが異なるコントローラーの種類で何を表しているのかを調べておくことをお勧めします。カメラに向くまで手をつながってください この設定をアクティブにすると、ソルバーは、メニューが視線入力と十分に揃うまで手の回転に従い、カメラに向いているポイントになります。 この動作は、HandConstraintSolver の SolverRotationBehavior を LookAtTrackedObject から LookAtMainCamera に変更することで機能します。これは、ソルバーによる GazeAlignment 角度が異なるためです。

アクティブ化イベント: 現在、
HandConstraint
は 4 つのアクティブ化イベントをトリガーします。 これらのイベントは、さまざまな組み合わせで使用して一意のHandConstraint
動作を作成できます。これらの動作の例については、MRTK/Examples/Demos/HandTracking/Scenes/
の HandBasedMenuExample シーンを参照してください。- OnHandActivate: 手が IsHandActive メソッドを満たすとトリガーされます。
- OnHandDeactivate: IsHandActive メソッドが満たされなくなったときにトリガーされます。
- OnFirstHandDetected: 手の追跡状態がビュー内の手からビューの最初の手に変わるときに発生します。
- OnLastHandLost: 手の追跡状態が、少なくとも 1 つの手のビューからビュー内の手に変わるときに発生します。
ソルバーのアクティブ化/非アクティブ化ロジック: 現在、
HandConstraintPalmUp
ロジックをアクティブ化および非アクティブ化するための推奨事項は、オブジェクトを無効または有効にするのではなく、SolverHandler の UpdateSolver 値を使用して行うことです。 この動作は、アタッチされたメニューの ManipulationHandler "OnManipulationStarted/Ended" イベントの後にトリガーされるエディター ベースのフックを使用して、サンプル シーンで確認できます。-
ハンド制約ロジックの停止: ハンド制約付きオブジェクトをアクティブ化/非アクティブ化ロジックを停止 (または実行しない) するように設定する場合は、HandConstraintPalmUp を無効にするのではなく、UpdateSolver を False に設定します。
- 視線入力ベース (または非視線入力ベース) の再アタッチ ロジックを有効にする場合は、HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine() 関数を呼び出してフォローアップします。 この呼び出しによってコルーチンがトリガーされ、"IsValidController" 条件が満たされた場合に引き続きチェックされ、UpdateSolver が True に設定されます (または、オブジェクトが無効になった場合)。
- 手制約ロジックの開始: 手の制約付きオブジェクトを設定して(アクティブ化条件を満たしているかどうかに基づいて) 手の後を再び開始する場合は、SolverHandler の UpdateSolver を true に設定します。
-
ハンド制約ロジックの停止: ハンド制約付きオブジェクトをアクティブ化/非アクティブ化ロジックを停止 (または実行しない) するように設定する場合は、HandConstraintPalmUp を無効にするのではなく、UpdateSolver を False に設定します。
ロジックの再アタッチ: 現在、
HandConstraintPalmUp
は、SolverHandler の UpdateSolver が True かどうかに関係なく、追跡対象のポイントにターゲット オブジェクトを自動的に再アタッチできます。 この動作は、HandConstraintPalmUp の StartWorldLockReattachCheckCoroutine() 関数をワールド ロックした後に呼び出すことによって処理されます (この場合は、SolverHandler の UpdateSolver を実質的に False に設定します)。