2019年12月16日月曜日

[HoloLens Advent Calendar 2019] 16日目 Mixed Realty Tookit Unity v2 HandConstraint.csのOnHandActivateの呼び出しタイミングについて

お疲れ様です。ZuQ9->Nnです。
この記事は、HoloLens Advent Calendar 2019、16日目 2019/12/16 の内容です。
 Mixed Realty Tookit Unity v2(以下MRTKv2)に
ハンドトラッキングを扱うHandConstraint.csというスクリプトがあります。

Class HandConstraint

Provides a solver that constrains the target to a region safe for hand constrained interactive content. This solver is intended to work with IMixedRealityHand but also works with IMixedRealityController. public class HandConstraint : Solver protected HandBounds handBounds protected IMixedRealityController trackedController When a hand is activated for tracking, should the cursor(s) be disabled on that hand?

HandConstraint.csは、Provides a solver that constrains the target to a region safe for hand constrained interactive content.
つまり、手の領域にあるオブジェクトに対して制約をつけて、手が見えたり隠れたりするときにイベントを実行するScriptです。
HandConstraint.csにはOnFirstHandDetected、OnHandActivate、OnHandDeactivate、 OnHandDeactivateというイベントが定義されています。

OnFirstHandDetectedは、Event which is triggered when zero hands to one hand is tracked.
日本語に直すとゼロ本の手の片手がトラッキングされたときにトリガーとなるイベント

OnHandActivateは、Event which is triggered when a hand begins being tracked.
手がトラッキング開始されたときにトリガーとなるイベント

OnHandDeactivateは、Event which is triggered when a hand stops being tracked. 手がトラッキング終了されたときにトリガーとなるイベント

OnLastHandLostは、Event which is triggered when all hands are lost. すべての手がトラッキングが失われたきにトリガーとなるイベント

となっています。ふと、OnFirstHandDetectedとOnHandActivateのタイミングってどう違うのだろう?そんな純粋な気持ちで調べたら。。。
なんだか思っていた結果と違ったので、

自分のメモ用にまとめておきます。 プロジェクトの作成、
Microsoft.MixedReality.Toolkit.Unity.Foundation.2.1.0.unitypackageのインポート
UnityのMixed Relaity ToolkitメニューからAdd to Scene and Configureを選択する等はいつも通り行ってください。
わからない方は、以前の記事を参考にしてください。

HierarchyのCreate > 3D Object > 3D Textを作成

これはデバックの文字列を画面に表示させるためのテキストです。
画面で確認できるように3D TextのTransFormや設定を行ってください。
僕は今回、Transform x:0, y:0, z:20 、Textは空に
Text MeshのAnchor Middle Center、Aligiment Center、Font Size 50としました。

HierarchyのCreate > Create Emptyで空のオブジェクトを作成

特に名前は何でもいいのですが、今回は、HandConstraintTestとしました。

HierarchyのHandConstraintTestを選択、
InspectorからAdd CompnentでHandConstraintを選択してアタッチ

更に、Add CompnentのNew ScriptでScriptを追加

Script名は何でも良いのですが、 今回は HandConstraintTest.csとしました。

中身は、こんな感じ HierarchyのNew TextをHandConstraintTest(Script)のTextにアタッチ


HandConstraintの各イベントにHandConstraintTestのメソッドを対応させます。
OnHandActivate : AfterHandActivate
OnHandDeactivate : AfterHandDeactivate
OnFirstHandDetected: AfterFirstHandDetected
OnLastHandLost: AfterHandLost

これでUnityを実行すると、このような感じになりました。

動画では、少しわかりにくいので、スクリーンショットでも解説します。
Unityを実行した直後は、OnLastHandLost、OnHandDeactivateが実行されます。

次に手を表示したときには、OnFirstHandDetectedのみ実行されます。

つまり、このタイミングでは、OnHandActivateは実行されません
手を非表示にしたときは、OnLastHandLostが呼び出されます。

では、いつ、OnHandActivateが呼び出されるのでしょうか?
結論から言うと、Unityの設定を変更しなければ、OnHandActivateは呼び出されません。

HandConstraint.csをアタッチすると、
Solver Handler.csもアタッチされています。

Class SolverHandler

This class handles the solver components that are attached to this GameObject public class SolverHandler : MonoBehaviour protected Handedness currentTrackedHandedness protected Handedness preferredTrackedHandedness protected readonly List solvers Add an additional offset of the tracked object to base the solver on. Useful for tracking something like a halo position above your head or off the side of a controller.
Solver Handler.csは、GameObjectにアタッチして、オブジェクトの位置と方向を計算するコンポーネントを提供します。
HierarchyからHandConstraintTestを選択、
InspectorでSolver HandlerのTracked Target Typeを確認してください。
最初の設定は、Headになっています。
つまり、頭に追随する設定なのです。

Solver HandlerのTracked Target Typeのドロップダウンから
Hand Jointを選択し。 手に追随する設定に変更します。


もう一度、Unityを実行するとこのような感じになります。

今回は、手を表示した時点で、
OnFirstHandDetected、OnHandActivateの二つのイベントが実行されました。


InspectorでSolver HandlerのTracked HandnessをBothからRightやLeftにすると
右手が表示されたときのみ、左手が表示されたときのみといった制御を行うことができます。

Solver HandlerのTracked Hand JointをPalm以外にも変更してみましたが、
OnFirstHandDetected、OnHandActivateの二つのイベントが実行されました。
しかし、これはUnity Editorで実行しているからかもしれませんね。

もしかしたら実機で、Tracked Hand JointをThumbTipにした場合、
親指を隠した状態で手を表示し、親指を立てたときのみ
OnHandActivateが実行される可能性があるのでは?
と思ったのですが、Noneにしてもイベントが実行されました。
なので、おそらく、Tracked Hand Jointは、OnHandActivateの実行タイミングとは関係ないと考えています。
Tracked Hand Jointは、オブジェクトをトラッキングするときの位置のみに利用するのでしょう。

しかし、これだけではありません、OnHandActivateイベントは、
HandConstraintPalmUp.csをアタッチした場合では、また別のタイミングで実行されるのです。

一度、InspectorのHandConstraintの歯車アイコンをクリックし、
Remove ComponentでHandConstraintをRemoveします。

InspectorのAdd ComponentからHandConstraintPalmUpを選択しアタッチします。

HandConstraintPalmUpの各イベントにHandConstraintTestのメソッドを対応させます。
OnHandActivate : AfterHandActivate
OnHandDeactivate : AfterHandDeactivate
OnFirstHandDetected: AfterFirstHandDetected
OnLastHandLost: AfterHandLost

Unityを実行するとこのような感じになります。

こちらもスクリーンショットで開設します。まず、手を表示したときは、
OnFirstHandDetectedのみ実行されます。

そして手を回転させて、手のひらが表示されたタイミングで
OnHandActivateが実行されます。

Solver HandlerのTracked Hand JointをPalm以外にも変更してみましたが、
Unityでは同じタイミングでイベントが実行されました。

Tracked Target TypeをHead、頭に戻して確認したところ
手のひらが表示されたタイミングでは、OnHandActivateが実行され無い結果となりました。

実機でどのように動くか、確認したい。。欲求が高まりましたが、
おそらく、イベントの実行タイミングはUnity Editorの時と変わらないと考えるのが妥当です。

とりあえずUnity上で確認した動きを表にしてまとめました。

Solver Handler
Tracked Target Type
手を表示した時の
イベント
手のひらを
表示したときのイベント
HandConstraint Head OnFirstHandDetected -

Hand Joint OnFirstHandDetected
OnHandActivate
-
HandConstraintPalmUp Head OnFirstHandDetected -

Hand Joint OnFirstHandDetected OnHandActivate

ちょっと自信が無いので、間違いがあったらご指摘ください。。
よろしくお願いいたします。

0 件のコメント:

コメントを投稿