眼球支援的目標選取 - MRTK2
此頁面討論存取眼球注視數據和眼球注視特定事件的不同選項,以在 MRTK 中選取目標。 眼球追蹤可讓您使用使用者查看的其他輸入,例如 手部追蹤 和 語音命令等信息組合,快速且輕鬆選取目標:
- 看起來 & 說 「選取」 (預設語音命令)
- & 說 出「分解」 或 「快顯」 (自定義語音命令)
- [& 藍牙] 按鈕
- 查看 & 捏合 (,也就是將手放在您前面,並將您的指紋和食指放在一起)
- 請注意,若要運作, 必須停用手部光線
若要使用眼部注視選取全像攝影內容,有數個選項:
這可視為您排定優先順序的數據指標。 根據預設,如果手部處於檢視狀態,則這會是手部光線。 如果沒有手部處於檢視中,則優先順序的指標會是頭部或眼睛注視。 因此請注意,如果使用手部光線,則根據目前的設計頭部或眼球注視,會隱藏為游標輸入。
例如:
使用者想要選取遠距全像攝影按鈕。 身為開發人員,您想要提供彈性的解決方案,讓用戶能夠在各種情況下達成此工作:
- 向上移至按鈕並加以點選
- 從距離查看它,然後說「選取」
- 以手部光線和執行捏合的按鈕為目標 在此案例中,最有彈性的解決方案是使用主要焦點處理程式,因為它會在目前排定優先順序的主要焦點指標觸發事件時通知您。 請注意,如果已啟用手部光線,當手部進入檢視時,就會停用頭部或眼睛注視焦點指標。
重要
請注意,如果已啟用手部光線,當手部進入檢視時,就會停用頭部或眼睛注視焦點指標。 如果您想要支援 「外觀和捏合」 互動,您必須停用手部光線。 在我們的眼球追蹤範例場景中,我們已停用手部光線,以允許使用眼睛 + 手部動作來展示更豐富的互動,請參閱例如 眼球支援的定位。
在某些情況下,您可能想要更明確哪些類型的焦點指標可以觸發特定事件,並允許同時使用多個遠距互動技術。
例如:在您的應用程式中,使用者可以使用遠手光線來操作某些全像攝影機械設定,例如抓取並按住一些遠的全像攝影引擎元件,並就地保存它們。 這麼做時,用戶必須完成一些指示,並記下其進度,方法是標示一些複選框。 如果使用者的手 不忙碌,則只要觸碰複選框,或使用手部光線加以選取會是直覺的。 不過,如果使用者的手部忙碌中,如同在我們的案例中保留一些全像攝影引擎元件,您想要讓使用者使用眼睛注視順暢地卷動指示,並直接查看複選框並說「核取它!」。
若要啟用此功能,您必須使用與核心 MRTK FocusHandlers 無關的眼球特有 EyeTrackingTarget 腳本,並將在下面進一步討論。
1.使用泛型焦點和指標處理程式
如果正確設定眼球追蹤 (請參閱 基本 MRTK 設定以使用眼球追蹤) ,讓用戶能夠使用眼睛選取全像投影,與任何其他焦點輸入 (相同,例如頭部注視或手部光線) 。這提供彈性方式的優點,可讓您根據使用者的需求在 MRTK 輸入指標配置檔中定義主要焦點類型,同時讓程式代碼保持不變,以彈性的方式與您的全像投影互動。 這可讓您在頭部或眼睛注視之間切換,而不需變更一行程式代碼,或將手部光線取代為眼部目標,以進行遠距互動。
專注於全像投影
若要偵測全像投影何時聚焦,請使用提供您兩個介面成員的 『IMixedRealityFocusHandler』 介面: OnFocusEnter 和 OnFocusExit。
以下是 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、OnPointerDown 和 OnPointerClicked。
在下列範例中,我們會查看全像投影並捏合或說「選取」來變更全像投影的色彩。
觸發事件的必要動作是由定義, 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
建立暫留回饋,以固定方向和固定速度 (,而不是在查看時從上方) 旋轉範例。 您只需要從 EyeTrackingTarget 的 WhileLookingAtTarget () 事件觸發全像攝影 Gem 的旋轉。 以下是更多詳細資料:
建立包含公用函式的泛型腳本,以旋轉它所附加的 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; } } }
將
EyeTrackingTarget
腳本新增至您的目標 GameObject,並參考 UnityEvent 觸發程式中 的 RotateTarget () 函式,如下所示:
範例 #3:快顯這些 Gem,也稱為 多重模式眼部注視支援的目標選取專案
在上一個範例中,我們已示範如何偵測是否查看目標,以及如何觸發該回應。 接下來,讓我們使用的 EyeTrackingTarget
OnSelected () 事件,讓 Gem 分解。 有趣的 部分是如何 觸發選取專案。
EyeTrackingTarget
可讓您快速指派不同的方法來叫用選取專案:
捏合手勢:將 [選取動作] 設定為 [選取] 會使用默認手勢來觸發選取專案。 這表示使用者可以直接舉起手,並捏合其指紋和食指,以確認選取專案。
說 「選取」:使用預設語音命令 「Select」 來選取全像投影。
說 出「分解」 或 「Pop」:若要使用自定義語音命令,您必須遵循兩個步驟:
設定自定義動作,例如 「DestroyTarget」。
- 瀏覽至 MRTK -> 輸入 -> 輸入動作
- 按兩下 [新增動作]
設定觸發此動作的語音命令,例如 「分解」 或 「Pop」
- 瀏覽至 MRTK -> 輸入 -> 語音
- 點選 [新增語音命令]
- 建立您剛才建立的動作關聯
- 指派 KeyCode 以允許透過按下按鈕觸發動作
選取 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 會回應其是否要查看,而頂端場景功能表按鈕則會改為使用主要輸入指標 (您的手) 。