次の方法で共有


目でサポートされるターゲットの選択 — MRTK2

MRTK

このページでは、目の視線入力データと視線入力固有のイベントにアクセスして MRTK のターゲットを選択するためのさまざまなオプションについて説明します。 視線追跡を使用すると、ユーザーが見ているものに関する情報を 手の追跡音声コマンドなどの追加入力と組み合わせて使用して、迅速かつ簡単にターゲットを選択できます。

  • "選択" と & 見る (既定の音声コマンド)
  • "爆発" または "Pop" と言う & を見る (カスタム音声コマンド)
  • Bluetooth ボタン & 見る
  • ピンチ & 見る(つまり、目の前で手を上げ、親指と人差し指を一緒に持ち込む)

視線入力を使用してホログラフィック コンテンツを選択するには、いくつかのオプションがあります。

1. プライマリ フォーカス ポインターを使用します。

これは、優先順位付けされたカーソルとして認識できます。 既定では、手が表示されている場合、これはハンド レイになります。 手が表示されていない場合、優先順位付けされたポインターは頭または目の視線入力になります。 したがって、手の光線を使用すると、現在のデザインの頭や目の視線入力に基づいてカーソル入力が抑制されることに注意してください。

例:

ユーザーは、離れたホログラフィック ボタンを選択する必要があります。 開発者は、ユーザーがさまざまな条件でこのタスクを達成できる柔軟なソリューションを提供したいと考えています。

  • ボタンまで歩いて突っ込む
  • 遠くから見て「選択」と言う
  • ハンド レイを使用してボタンをターゲットにし、ピンチを実行する この場合、最も柔軟な解決策は、現在優先順位が設定されているプライマリ フォーカス ポインターによってイベントがトリガーされるたびに通知されるため、プライマリ フォーカス ハンドラーを使用することです。 手の光線が有効になっている場合、手が表示されるとすぐに頭または目の視線入力フォーカス ポインターが無効になります。

重要

手の光線が有効になっている場合、手が表示されるとすぐに頭または目の視線入力フォーカス ポインターが無効になります。 "ルック アンド ピンチ" 操作をサポートする場合は、ハンド レイを無効にする必要があります。 視線追跡のサンプル シーンでは、手の光線を無効にして、目と手の動きを使用して、より豊かな相互作用を示せるようにしました。例えば 、目でサポートされる位置決めを参照してください。

2.目のフォーカスと手の光線の両方を同時に使用します。

特定のイベントをトリガーし、複数の遠距離対話手法を同時に使用できるフォーカス ポインターの種類をより具体的にしたい場合があります。

たとえば、アプリでは、ユーザーは遠くの手の光線を使用して、いくつかのホログラフィックの機械的セットアップを操作できます。たとえば、離れたホログラフィック エンジンパーツをつかんで保持し、所定の位置に保持します。 その間、ユーザーはいくつかの指示を実行し、いくつかのチェックボックスをオフにして進捗状況を記録する必要があります。 ユーザーの手がビジー状態でない場合は、チェックボックスにタッチするか、手の光線を使用して選択するのが本能的です。 ただし、ユーザーが手を忙しくしている場合は、ホログラフィック エンジンパーツを所定の位置に保持している場合は、ユーザーが目の視線入力を使用して指示をシームレスにスクロールし、単にチェックボックスを見て"チェック!"と言えるようにする必要があります。

これを有効にするには、コア MRTK FocusHandlers から独立した目に固有の EyeTrackingTarget スクリプトを使用する必要があります。これについては、以下で詳しく説明します。

1. 汎用フォーカスとポインター ハンドラーを使用する

視線追跡が正しく設定されている場合 (「 視線追跡を使用するための基本的な MRTK セットアップ」を参照)、ユーザーが目を使用してホログラムを選択できるようにする方法は、他のフォーカス入力 (頭の視線入力や手の光線など) の場合と同じです。これにより、ユーザーのニーズに応じて MRTK 入力ポインター プロファイルでメイン フォーカスの種類を定義し、コードを変更せずにホログラムを操作する柔軟な方法の優れた利点が得られます。 これにより、コード行を変更せずに頭または目の視線入力を切り替えたり、遠距離の相互作用を対象とする手の光線を視線に置き換えたりできます。

ホログラムに焦点を合わせる

ホログラムがいつフォーカスされているかを検出するには、OnFocusEnterOnFocusExit の 2 つのインターフェイス メンバーを提供する 'IMixedRealityFocusHandler' インターフェイスを使用します。

次に示すのは、 ColorTap.cs から見たときにホログラムの色を変更する簡単な例です。

public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler
{
    void IMixedRealityFocusHandler.OnFocusEnter(FocusEventData eventData)
    {
        material.color = color_OnHover;
    }

    void IMixedRealityFocusHandler.OnFocusExit(FocusEventData eventData)
    {
        material.color = color_IdleState;
    }
    ...
}

フォーカスのあるホログラムの選択

フォーカスのあるホログラムを選択するには、 PointerHandler を 使用して入力イベントをリッスンして選択内容を確認します。 たとえば、 IMixedRealityPointerHandler を追加すると、単純なポインター入力に反応します。 IMixedRealityPointerHandler インターフェイスでは、OnPointerUp、OnPointerDownOnPointerClicked の 3 つのインターフェイス メンバーを実装する必要があります。

次の例では、ホログラムを見て、ピンチまたは "選択" と言うことで、ホログラムの色を変更します。 イベントをトリガーするために必要なアクションは、eventData.MixedRealityInputAction == selectActionによって定義されます。それにより、Unity エディターでselectActionの種類を設定できます。既定では"選択" アクションです。 使用可能な MixedRealityInputActions の種類は、MRTK 構成プロファイル ->Input ->Input Actions を使用して MRTK プロファイルで構成できます。

public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler, IMixedRealityPointerHandler
{
    // Allow for editing the type of select action in the Unity Editor.
    [SerializeField]
    private MixedRealityInputAction selectAction = MixedRealityInputAction.None;
    ...

    void IMixedRealityPointerHandler.OnPointerUp(MixedRealityPointerEventData eventData)
    {
        if (eventData.MixedRealityInputAction == selectAction)
        {
            material.color = color_OnHover;
        }
    }

    void IMixedRealityPointerHandler.OnPointerDown(MixedRealityPointerEventData eventData)
    {
        if (eventData.MixedRealityInputAction == selectAction)
        {
            material.color = color_OnSelect;
        }
    }

    void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData) { }
}

視線入力固有の BaseEyeFocusHandler

目の視線入力が他のポインター入力と大きく異なる場合がある場合は、フォーカス入力が 視線入力 であり、現在はプライマリ入力ポインターである場合にのみ、必ず応答するようにすることをお勧めします。 このためには、視線追跡に固有の BaseEyeFocusHandler を使用し、 BaseFocusHandlerから派生します。 前述のように、視線視線入力のターゲットが現在プライマリ ポインター入力である場合にのみトリガーされます (つまり、ハンド レイがアクティブではありません)。 詳細については、「 視線入力と手のジェスチャをサポートする方法」を参照してください。

EyeTrackingDemo-03-Navigation (Assets/MRTK/Examples/Demos/EyeTracking/Scenes) の例を次に示します。 このデモでは、オブジェクトのどの部分が見えるかに応じて 2 つの 3D ホログラムが表示されます。ユーザーがホログラムの左側を見ると、その部分はユーザーに面した前面にゆっくりと移動します。 右側を見ると、その部分はゆっくりと前面に移動します。 これは、常にアクティブにしたくない動作であり、手の光線や頭の視線入力によって誤ってトリガーしたくない場合もあります。 OnLookAtRotateByEyeGazeをアタッチすると、見ている間に GameObject が回転します。

public class OnLookAtRotateByEyeGaze : BaseEyeFocusHandler
{
    ...

    protected override void OnEyeFocusStay()
    {
        // Update target rotation
        RotateHitTarget();
    }

    ...

    ///
    /// This function computes the rotation of the target to move the currently
    /// looked at aspect slowly to the front.
    ///
    private void RotateHitTarget()
    {
        // Example for querying the hit position of the eye gaze ray using EyeGazeProvider
        Vector3 TargetToHit = (this.gameObject.transform.position - InputSystem.EyeGazeProvider.HitPosition).normalized;

        ...
    }
}

の使用可能なイベントの完全な一覧については、API ドキュメントを確認してください。

  • OnEyeFocusStart: 視線視線入力線がこのターゲットのコライダーとの交差を 開始 するとトリガーされます。
  • OnEyeFocusStay: 視線視線入力線がこのターゲットのコライダーと交差 している間 にトリガーされます。
  • OnEyeFocusStop: このターゲットのコライダーとの交差を視線視線が 停止 するとトリガーされます。
  • OnEyeFocusDwell: 指定した時間、視線視線がこのターゲットのコライダーと交差するとトリガーされます。

2. 独立した視線入力固有の EyeTrackingTarget

最後に、 EyeTrackingTarget スクリプトを使用して、目ベースの入力を他のフォーカス ポインターから完全に独立して処理できるソリューションを提供します。

これには、次の 3 つの 利点があります

  • ホログラムがユーザーの目の視線入力にのみ反応していることを確認できます。
  • これは、現在アクティブなプライマリ入力とは独立しています。 そのため、複数の入力を一度に処理できます。たとえば、高速視線ターゲティングと手のジェスチャを組み合わせています。
  • Unity エディター内またはコードを使用して、既存の動作を迅速かつ便利に処理し、再利用できるように、いくつかのUnity イベントが既に設定されています。

また、次のような 欠点もあります。

  • 個別の入力を個別に処理するためのより多くの労力。
  • エレガントな劣化なし:目のターゲット設定のみをサポートします。 視線追跡が機能しない場合は、追加のフォールバックが必要です。

BaseFocusHandler と同様に、EyeTrackingTarget には、Unity エディター (下の例を参照) またはコードで AddListener() を使用して、便利にリッスンできる視線視線固有のUnity イベントがいくつか用意されています。

  • OnLookAtStart()
  • WhileLookingAtTarget()
  • OnLookAway()
  • OnDwell()
  • OnSelected()

次に、 EyeTrackingTarget を使用する方法の例をいくつか示します。

例 1: 目でサポートされるスマート通知

EyeTrackingDemo-02-TargetSelection (Assets/MRTK/Examples/Demos/EyeTracking/Scenes) では、目の視線入力に反応する "スマートな注意深い通知" の例を見つけることができます。 これらは、シーンに配置できる 3D テキスト ボックスであり、見ているとスムーズに拡大し、ユーザーに向かって回転して読みやすくします。 ユーザーが通知を読んでいる間、情報は鮮明で明確に表示され続けます。 読み取って通知から離すと、通知は自動的に無視され、フェードアウトします。これを実現するために、視線追跡に固有ではない一般的な動作スクリプトがいくつかあります。次に示します。

この方法の利点は、同じスクリプトをさまざまなイベントで再利用できることです。 たとえば、ホログラムは、音声コマンドに基づいて、または仮想ボタンを押した後にユーザーの向きを開始できます。 これらのイベントをトリガーするには、GameObject にアタッチされている EyeTrackingTarget スクリプトで実行する必要があるメソッドを参照するだけです。

"スマートな注意深い通知" の例では、次の処理が行われます。

  • OnLookAtStart(): 通知が 開始します。...

    • FaceUser。Engage: ...をユーザーに向ける。
    • ChangeSize。Engage: ...サイズの増加 (指定された最大スケールまで)。
    • BlendOut。Engage: ...(より微妙なアイドル状態にされた後)、より多くのブレンドが開始されます。
  • OnDwell(): 通知が十分に確認されたことを BlendOut スクリプトに通知します。

  • OnLookAway(): 通知が 開始します。...

    • FaceUser.Disengage: ...元の方向に戻します。
    • ChangeSize.Disengage: ...元のサイズに戻します。
    • BlendOut.Disengage: ...ブレンドを開始する - OnDwell() がトリガーされた場合は、完全にブレンドして破棄し、それ以外の場合はアイドル状態に戻します。

設計上の考慮事項: ここでの楽しいエクスペリエンスの鍵は、ユーザーの目の視線入力に常に反応して不快感を引き起こさないように、これらの動作の速度を慎重に調整することです。 そうしないと、これはすぐに非常に圧倒的に感じることができます。

ターゲット通知

例 2: Holographic gem を見るとゆっくり回転する

例 1 と同様に、 EyeTrackingDemo-02-TargetSelection (Assets/MRTK/Examples/Demos/EyeTracking/Scenes) シーンでホログラフィック Gem のホバー フィードバックを簡単に作成できます。これは、見たときに一定の方向と一定の速度 (上からの回転の例とは対照的) にゆっくりと回転します。 必要なのは、 EyeTrackingTargetWhileLookingAtTarget() イベントからホログラフィック gem の回転をトリガーするだけです。 いくつかの詳細を次に示します。

  1. アタッチされている GameObject をローテーションするパブリック関数を含む汎用スクリプトを作成します。 RotateWithConstSpeedDir.csの例を次に示します。ここでは、Unity エディターから回転方向と速度を調整できます。

    using UnityEngine;
    
    namespace Microsoft.MixedReality.Toolkit.Examples.Demos.EyeTracking
    {
        /// <summary>
        /// The associated GameObject will rotate when RotateTarget() is called based on a given direction and speed.
        /// </summary>
        public class RotateWithConstSpeedDir : MonoBehaviour
        {
            [Tooltip("Euler angles by which the object should be rotated by.")]
            [SerializeField]
            private Vector3 RotateByEulerAngles = Vector3.zero;
    
            [Tooltip("Rotation speed factor.")]
            [SerializeField]
            private float speed = 1f;
    
            /// <summary>
            /// Rotate game object based on specified rotation speed and Euler angles.
            /// </summary>
            public void RotateTarget()
            {
                transform.eulerAngles = transform.eulerAngles + RotateByEulerAngles * speed;
            }
        }
    }
    
  2. 次のスクリーンショットに示すように、 EyeTrackingTarget スクリプトをターゲット GameObject に追加し、UnityEvent トリガーで RotateTarget() 関数を参照します。

    EyeTrackingTarget サンプル

例 3: これらの宝石をマルチモーダルの視線入力でサポートされているターゲット選択としてポップする

前の例では、ターゲットが見られたかどうかを検出する方法と、それに対する反応をトリガーする方法を簡単に示しました。 次に、EyeTrackingTargetOnSelected() イベントを使用して宝石を爆発させます。 興味深いのは、選択 がどのように トリガーされるかです。 EyeTrackingTargetを使用すると、選択を呼び出すさまざまな方法をすばやく割り当てることができます。

  • ピンチ ジェスチャ: [アクションの選択] を [選択] に設定すると、既定のハンド ジェスチャを使用して選択がトリガーされます。 つまり、ユーザーは手を上げて親指と人差し指を一緒につまんで選択を確認できます。

  • "選択" と言う: ホログラムを選択するために、既定の音声コマンド "選択" を使用します。

  • "爆発" または "ポップ" と言う: カスタム音声コマンドを使用するには、次の 2 つの手順に従う必要があります。

    1. "DestroyTarget" などのカスタム アクションを設定する

      • MRTK -> 入力 -> 入力アクションに移動します
      • [新しいアクションの追加] をクリックします
    2. "爆発" や "Pop" などのこのアクションをトリガーする音声コマンドを設定する

      • MRTK -> 入力 -> Speech に移動します
      • [新しい音声コマンドの追加] をクリックします
        • 先ほど作成したアクションを関連付ける
        • ボタンを押してアクションをトリガーできるように KeyCode を割り当てる

音声コマンド EyeTrackingTarget サンプル

宝石が選択されると爆発し、音が鳴り、消えます。 これは、 HitBehaviorDestroyOnSelect スクリプトによって処理されます。 次の 2 つの方法があります。

  • Unity エディター: 各 gem テンプレートに添付されているスクリプトを、Unity エディターの OnSelected() Unity イベントにリンクするだけです。
  • コード内: GameObjects をドラッグ アンド ドロップしない場合は、スクリプトにイベント リスナーを直接追加することもできます。
    HitBehaviorDestroyOnSelect スクリプトで行った方法の例を次に示します。
/// <summary>
/// Destroys the game object when selected and optionally plays a sound or animation when destroyed.
/// </summary>
[RequireComponent(typeof(EyeTrackingTarget))] // This helps to ensure that the EyeTrackingTarget is attached
public class HitBehaviorDestroyOnSelect : MonoBehaviour
{
    ...
    private EyeTrackingTarget myEyeTrackingTarget = null;

    private void Start()
    {
        myEyeTrackingTarget = this.GetComponent<EyeTrackingTarget>();

        if (myEyeTrackingTarget != null)
        {
            myEyeTrackingTarget.OnSelected.AddListener(TargetSelected);
        }
    }

    ...

    ///
    /// This is called once the EyeTrackingTarget detected a selection.
    ///
    public void TargetSelected()
    {
        // Play some animation
        // Play some audio effect
        // Handle destroying the target appropriately
    }
}

例 4: 手の光線と視線入力を一緒に使用する

手の光線は、頭と目の視線入力のターゲットよりも優先されます。 つまり、手の光線が有効になっている場合、手が見える瞬間に、手の光線がプライマリ ポインターとして機能します。 ただし、ユーザーが特定のホログラムを見ているかどうかを検出しながら、手の光線を使用したい場合があります。 簡単! 基本的に、次の 2 つの手順が必要です。

1. ハンド レイを有効にする: ハンド レイを有効にするには、ツールキット -> 入力 -> ポインター Mixed Realityに移動します。 EyeTrackingDemo-00-RootScene で、すべての視線追跡デモ シーンに対して Mixed Reality Toolkit が 1 回構成されている場合は、EyeTrackingDemoPointerProfile が表示されます。 新しい 入力プロファイル をゼロから作成するか、現在の視線追跡プロファイルを適応させることができます。

  • ゼロから: [ ポインター ] タブで、コンテキスト メニューから DefaultMixedRealityInputPointerProfile を選択します。 これは、ハンド レイが既に有効になっている既定のポインター プロファイルです。 既定のカーソル (不透明な白いドット) を変更するには、プロファイルを複製し、独自のカスタム ポインター プロファイルを作成するだけです。 次に、視線カーソル プレハブの下の DefaultCursorを EyeGazeCursor に置き換えます。
  • 既存の EyeTrackingDemoPointerProfile に基づいて:EyeTrackingDemoPointerProfile をダブルクリックし、[ポインター オプション] の下に次のエントリを追加します。
    • コントローラーの種類:'多関節ハンド', 'Windows Mixed Reality'
    • 利き手: Any
    • ポインター プレハブ: DefaultControllerPointer

2. ホログラムが見られたことを検出する:EyeTrackingTarget スクリプトを使用して、上記のようにホログラムが見られたことを検出できるようにします。 また、手の光線が有効かどうかに関係なく、目の視線入力 (カーソルなど) に続くホログラムが表示されるため、 FollowEyeGaze サンプル スクリプトを見てインスピレーションを得ることもできます。

これで、視線追跡のデモ シーンを開始すると、手から光線が現れるはずです。 たとえば、視線追跡ターゲットの選択デモでは、半透明の円は目の視線入力に従っており、宝石は見ているかどうかに応答しますが、上部のシーン メニュー ボタンは代わりにプライマリ入力ポインター (手) を使用します。


"MixedRealityToolkit での視線追跡" に戻る