ハンド メニュー — MRTK2
ユーザーはハンド メニューを使用して、手にアタッチされた 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 が非アクティブされてメニューがワールド ロックされます。 また、タスクの終了時にユーザーがメニューを閉じることができる [閉じる] ボタンが表示されます。 操作終了時イベントでは、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
プロパティで使用できるツール ヒントを参照してください。 いくつかのプロパティについては、以下で詳しく説明します。
[セーフ ゾーン]: セーフ ゾーンは、手の上でコンテンツを拘束する場所を指定します。 手との重なりを避け、対話品質を向上させるために、コンテンツを Ulnar 側に配置することをお勧めします。 セーフ ゾーンは、カメラのビューに直交する平面に投影された手の向きを取得し、手を囲む境界ボックスに対してレイキャストすることによって計算されます。 セーフ ゾーンは
IMixedRealityHand
で動作するように定義されていますが、他の種類のコントローラーでも動作します。 各セーフ ゾーンが異なるコントローラーの種類で何を表しているのかを調べるのが推奨されます。カメラに向かうまで手を追う この設定をアクティブにすると、メニューが視線入力に十分に合わせられるまで、ソルバーは手の回転に従います。この時点でカメラに面します。 この動作は、HandConstraintSolver の SolverRotationBehavior を LookAtTrackedObject から LookAtMainCamera に変更することで機能します。これは、ソルバーによる GazeAlignment 角度が変化するためです。
[アクティブ化イベント]: 現在、
HandConstraint
では 4 つのアクティブ化イベントがトリガーされます。 これらのイベントは、さまざまな組み合わせで使用して一意HandConstraint
の動作を作成できます。これらの動作の例については、HandBasedMenuExample シーンMRTK/Examples/Demos/HandTracking/Scenes/
を参照してください。- 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 に設定します)。