眼球支援的目標選取 - MRTK2

MRTK

此頁面討論存取眼球注視數據和眼球注視特定事件的不同選項,以在 MRTK 中選取目標。 眼球追蹤可讓您使用使用者查看的其他輸入,例如 手部追蹤語音命令等信息組合,快速且輕鬆選取目標:

  • 看起來 & 說 「選取」 (預設語音命令)
  • & 說 出「分解」「快顯」 (自定義語音命令)
  • [& 藍牙] 按鈕
  • 查看 & 捏合 (,也就是將手放在您前面,並將您的指紋和食指放在一起)

若要使用眼部注視選取全像攝影內容,有數個選項:

1.使用主要焦點指標:

這可視為您排定優先順序的數據指標。 根據預設,如果手部處於檢視狀態,則這會是手部光線。 如果沒有手部處於檢視中,則優先順序的指標會是頭部或眼睛注視。 因此請注意,如果使用手部光線,則根據目前的設計頭部或眼球注視,會隱藏為游標輸入。

例如:

使用者想要選取遠距全像攝影按鈕。 身為開發人員,您想要提供彈性的解決方案,讓用戶能夠在各種情況下達成此工作:

  • 向上移至按鈕並加以點選
  • 從距離查看它,然後說「選取」
  • 以手部光線和執行捏合的按鈕為目標 在此案例中,最有彈性的解決方案是使用主要焦點處理程式,因為它會在目前排定優先順序的主要焦點指標觸發事件時通知您。 請注意,如果已啟用手部光線,當手部進入檢視時,就會停用頭部或眼睛注視焦點指標。

重要

請注意,如果已啟用手部光線,當手部進入檢視時,就會停用頭部或眼睛注視焦點指標。 如果您想要支援 「外觀和捏合」 互動,您必須停用手部光線。 在我們的眼球追蹤範例場景中,我們已停用手部光線,以允許使用眼睛 + 手部動作來展示更豐富的互動,請參閱例如 眼球支援的定位

2.同時使用眼睛焦點和手部光線:

在某些情況下,您可能想要更明確哪些類型的焦點指標可以觸發特定事件,並允許同時使用多個遠距互動技術。

例如:在您的應用程式中,使用者可以使用遠手光線來操作某些全像攝影機械設定,例如抓取並按住一些遠的全像攝影引擎元件,並就地保存它們。 這麼做時,用戶必須完成一些指示,並記下其進度,方法是標示一些複選框。 如果使用者的手 不忙碌,則只要觸碰複選框,或使用手部光線加以選取會是直覺的。 不過,如果使用者的手部忙碌中,如同在我們的案例中保留一些全像攝影引擎元件,您想要讓使用者使用眼睛注視順暢地卷動指示,並直接查看複選框並說「核取它!」。

若要啟用此功能,您必須使用與核心 MRTK FocusHandlers 無關的眼球特有 EyeTrackingTarget 腳本,並將在下面進一步討論。

1.使用泛型焦點和指標處理程式

如果正確設定眼球追蹤 (請參閱 基本 MRTK 設定以使用眼球追蹤) ,讓用戶能夠使用眼睛選取全像投影,與任何其他焦點輸入 (相同,例如頭部注視或手部光線) 。這提供彈性方式的優點,可讓您根據使用者的需求在 MRTK 輸入指標配置檔中定義主要焦點類型,同時讓程式代碼保持不變,以彈性的方式與您的全像投影互動。 這可讓您在頭部或眼睛注視之間切換,而不需變更一行程式代碼,或將手部光線取代為眼部目標,以進行遠距互動。

專注於全像投影

若要偵測全像投影何時聚焦,請使用提供您兩個介面成員的 『IMixedRealityFocusHandler』 介面: OnFocusEnterOnFocusExit

以下是 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 介面需要實作下列三個介面成員:OnPointerUpOnPointerDownOnPointerClicked

在下列範例中,我們會查看全像投影並捏合或說「選取」來變更全像投影的色彩。 觸發事件的必要動作是由定義, eventData.MixedRealityInputAction == selectAction 我們可以在 Unity 編輯器中設定 的型 selectAction 別,預設為 「選取」動作。 您可以透過 MRTK 組態配置檔 ->Input -Input ->Input Actions,在 MRTK 設定檔中設定可用的 MixedRealityInputActions 類型。

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) 的範例。 在此示範中,有兩個 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 檔,以取得 可用事件 BaseEyeFocusHandler的完整清單:

  • OnEyeFocusStart: 一旦眼睛注視光線 開始 與這個目標的碰撞器交集,就會觸發。
  • OnEyeFocusStay: 當眼睛注視光線與這個目標的碰撞器交集 觸發。
  • OnEyeFocusStop: 一旦眼睛注視光線 停止 與這個目標的碰撞器交集,就會觸發。
  • OnEyeFocusDwell: 一旦眼睛注視光線與這個目標的碰撞器交集一段時間,就會觸發。

2. 獨立眼部注視特定 EyeTrackingTarget

最後,我們會為您提供解決方案,讓您透過腳本完全獨立於其他焦點指標 EyeTrackingTarget 的眼球型輸入。

這有三 個優點

  • 您可以確定全像投影只會回應使用者的眼睛注視。
  • 這與目前作用中的主要輸入無關。 因此,您可以一次處理多個輸入,例如,結合快速眼球目標與手勢。
  • 已設定數個 Unity 事件,以便快速且方便處理和重複使用 Unity 編輯器中的現有行為,或透過程式代碼。

也有一些 缺點:

  • 更努力個別處理個別的輸入。
  • 沒有簡潔的降低:它只支援眼球目標。 如果眼球追蹤無法運作,您需要一些額外的後援。

BaseFocusHandler 類似, EyeTrackingTarget 已準備好數個眼部注視特定的 Unity 事件,您可以透過 Unity 編輯器輕鬆接聽 (請參閱下列範例) 或使用程式代碼中的 AddListener ()

  • 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:全像攝影 Gem 在查看時會緩慢旋轉

與範例 #1 類似,我們可以在 (Assets/MRTK/Examples/Demos/EyeTracking/Scenes) 場景中,輕鬆地為全像攝影 Gem EyeTrackingDemo-02-TargetSelection 建立暫留回饋,以固定方向和固定速度 (,而不是在查看時從上方) 旋轉範例。 您只需要從 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:快顯這些 Gem,也稱為 多重模式眼部注視支援的目標選取專案

在上一個範例中,我們已示範如何偵測是否查看目標,以及如何觸發該回應。 接下來,讓我們使用的 EyeTrackingTargetOnSelected () 事件,讓 Gem 分解。 有趣的 部分是如何 觸發選取專案。 EyeTrackingTarget可讓您快速指派不同的方法來叫用選取專案:

  • 捏合手勢:將 [選取動作] 設定為 [選取] 會使用默認手勢來觸發選取專案。 這表示使用者可以直接舉起手,並捏合其指紋和食指,以確認選取專案。

  • 「選取」:使用預設語音命令 「Select」 來選取全像投影。

  • 出「分解」「Pop」:若要使用自定義語音命令,您必須遵循兩個步驟:

    1. 設定自定義動作,例如 「DestroyTarget」。

      • 瀏覽至 MRTK -> 輸入 -> 輸入動作
      • 按兩下 [新增動作]
    2. 設定觸發此動作的語音命令,例如 「分解」「Pop」

      • 瀏覽至 MRTK -> 輸入 -> 語音
      • 點選 [新增語音命令]
        • 建立您剛才建立的動作關聯
        • 指派 KeyCode 以允許透過按下按鈕觸發動作

Voice 命令 EyeTrackingTarget 範例

選取 Gem 時,它會分解,讓音效消失。 這是由 HitBehaviorDestroyOnSelect 腳本處理。 您有兩個選擇:

  • 在 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:同時使用手部光線和眼睛注視輸入

手部光線優先於頭部和眼睛注視目標。 這表示,如果已啟用手部光線,當手部進入檢視時,手部光線會作為主要指標。 不過,在某些情況下,您可能想要使用手部光線,同時仍然偵測使用者是否正在查看特定的全像投影。 輕而易舉! 基本上,您需要兩個步驟:

1.啟用手部光線:若要啟用手部光線,請移至 Mixed Reality 工具組 -> 輸入 -> 指標。 在 EyeTrackingDemo-00-RootScene 中,Mixed Reality 工具組已針對所有眼球追蹤示範場景設定一次,您應該會看到 EyeTrackingDemoPointerProfile。 您可以從頭開始建立新的 輸入設定檔 ,或調整目前的眼球追蹤:

  • 從頭: 在 [ 指標] 索引 卷標中,從操作功能表中選取 DefaultMixedRealityInputPointerProfile 。 這是已啟用手部光線的預設指標配置檔! 若要變更預設數據指標 (不透明白點) ,只要複製配置檔並建立您自己的自定義指標配置檔即可。 然後將 DefaultCursor 取代為註視游標預製專案下的 EyeGazeCursor
  • 根據現有的 EyeTrackingDemoPointerProfile 按兩下 EyeTrackingDemoPointerProfile ,並在 [指標選項] 底下新增下列專案:
    • 控制器類型:「已表達的手部」、「Windows Mixed Reality」
    • 手部: 任何
    • 指標預製專案: DefaultControllerPointer

2. 偵測到全像投影已查看: 使用 EyeTrackingTarget 腳本來啟用偵測全像投影的查看方式,如上所述。 您也可以查看 FollowEyeGaze 範例腳本以取得靈感,因為這是在眼睛注視 (后顯示全像投影,例如游標) 是否啟用手部光線。

現在,當您開始眼球追蹤示範場景時,您應該會看到來自手部的光線。 例如,在眼球追蹤目標選取示範中,半透明圓形仍會遵循您的眼睛注視,而 Gem 會回應其是否要查看,而頂端場景功能表按鈕則會改為使用主要輸入指標 (您的手) 。


回到 「MixedRealityToolkit 中的眼球追蹤」