指標 - MRTK2
本文說明如何在實務上設定和回應指標輸入。 若要進一步瞭解如何在高階控制多個指標,請參閱 指標架構。
偵測到新的控制器時,指標會在執行時間自動實例。 多個指標可以附加至控制器。 例如,使用預設指標設定檔時,Windows Mixed Reality控制器會分別取得一條線和一個折線指標,以進行一般選取和遠端傳送。
指標設定
指標會透過 設定為 MRTK 中輸入系統的一 MixedRealityPointerProfile
部分。 此類型的設定檔會在 MRTK 組態偵測器中指派給 MixedRealityInputSystemProfile
。 指標設定檔會決定游標、執行時間可用的指標類型,以及這些指標彼此通訊的方式,以決定哪一個指標為作用中。
指向範圍 - 定義指標可以與 GameObject 互動的最大距離。
指向 Raycast 圖層遮罩 - 這是 LayerMasks 的優先順序陣列,可判斷任何指定指標可以互動的可能 GameObject,以及要嘗試的互動順序。 這可能有助於確保指標先與其他場景物件互動 UI 元素。
指標選項群組態
預設 MRTK 指標設定檔群組態包含下列指標類別和現用預製專案。 執行時間可供系統的指標清單定義在指標設定檔的 [ 指標選項 ] 底下。 開發人員可以使用這份清單來重新設定現有的指標、新增指標或刪除一個指標。
每個指標專案都是由下列資料集所定義:
控制器類型 - 指標有效的控制器集。
- 例如, PokePointer 負責使用手指「擷取」物件,而且預設會標示為僅支援已表達的手部控制器類型。 只有在控制器變成可用時,才會具現化指標,特別是 控制器類型 會定義可以使用這個指標預製專案建立的控制器。
手部 - 允許只針對特定手部具現化指標 (左/右)
注意
將 Pointer 專案的 Handedness 屬性設定為 None 會有效地從系統停用它,做為從清單中移除該指標的替代方案。
- 指標預製專案 - 此預製專案會在符合指定控制器類型和手部狀態的控制器開始追蹤時具現化。
可以有多個與控制器相關聯的指標。 例如,在 DefaultHoloLens2InputSystemProfile
(Assets/MRTK/SDK/Profiles/HoloLens2/) 與PokePointer、GrabPointer和DefaultControllerPointer (相關聯,也就是手部光線) 。
注意
MRTK 會在 Assets/MRTK/SDK/Features/UX/Prefabs/Pointers中提供一組指標預製專案。 只要它包含 Assets/MRTK/SDK/Features/UX/Scripts/Pointers 或任何其他實作 IMixedRealityPointer
的腳本,就可以建置新的自訂預製專案。
資料指標設定
注視游標可透過 GazeCursorPrefab
編輯器內的 屬性 MixedRealityInputSystemProfile
直接設定。 若要設定用於其他指標的資料指標,您必須變更對應 BaseControllerPointer
欄位中所使用的 CursorPrefab
預製專案。 若要以程式設計方式變更資料指標,請修改 BaseCursor
對應 IMixedRealityPointer
行為上的 屬性。
如需資料指標行為的實作範例,請參閱 Assets/MRTK/SDK/Features/UX/Prefabs/Cursors 中的資料指標預製專案。 特別是 ,DefaultGazeCursor 提供根據內容狀態變更游標圖形的強固實作。
預設指標類別
下列類別是可用的現用 MRTK 指標,並定義于上述預設 MRTK 指標設定檔 中。 資產 /MRTK/SDK/Features/UX/Prefabs/Pointers 下提供的每個指標預製專案都包含附加的其中一個指標元件。
遠方指標
LinePointer
LinePointer是基底指標類別,會從輸入來源繪製線條 (,也就是控制器) 指標方向,並支援以這個方向進行單一光線轉換。 一般而言,子系類別,例如 ShellHandRayPointer
和 teleport 指標會具現化並利用 (,這也會繪製線條來指出遠端傳送最終會位於) ,而不是主要提供通用功能的這個類別。
對於像是在、Vive 和 Windows Mixed Reality 的動作控制器,旋轉會符合控制器的旋轉。 對於其他控制器,例如HoloLens 2表達的手部,旋轉符合系統提供的指標姿勢。
CurvePointer
CurvePointer 藉由允許沿著曲線進行多步驟光線轉換,來擴充 LinePointer 類別。 這個基底指標類別適用于弧形實例,例如遠端傳送指標,其中線條一致地彎曲到參數。
ShellHandRayPointer
從 延伸的 LinePointer
ShellHandRayPointer實作會作為MRTK 指標設定檔的預設值。 DefaultControllerPointer預製專案會實作 ShellHandRayPointer
類別。
GGVPointer
也稱為 注視/手勢/語音 (GGV) 指標,GGVPointer 支援 HoloLens 1 樣式的外觀和點選互動,主要是透過注視和空中點選或注視和語音選取互動。 GGV 指標的位置和方向是由頭部的位置和旋轉所驅動。
TouchPointer
TouchPointer負責使用 Unity Touch 輸入 (,也就是觸控式) 。 這些是「遠距互動」,因為觸控螢幕的動作會將相機的光線轉換成場景中可能遠處的位置。
MousePointer
MousePointer可讓螢幕對世界光線廣播進行遠距互動,但用於滑鼠而非觸控。
注意
在 MRTK 中預設無法使用滑鼠支援,但可以將類型的 MouseDeviceManager
新輸入資料提供者新增至 MRTK 輸入設定檔,並將 指派給 MixedRealityMouseInputProfile
資料提供者來啟用。
接近指標
PokePointer
PokePointer可用來與支援「近乎互動可觸控」的遊戲物件互動。 是具有附加 NearInteractionTouchable
腳本的 GameObjects。 在 UnityUI 的情況下,此指標會尋找 NearInteractionTouchableUnityUIs。 PokePointer 會使用 SphereCast 來判斷最接近的可觸控元素,並用來為可按下按鈕之類的專案提供電源。
使用元件設定 GameObject NearInteractionTouchable
時,請務必設定 localForward 參數,以指出按鈕的前端或其他應該可觸控的物件。 也請確定可觸控的 界限 符合可觸控物件的界限。
實用的 Poke 指標屬性:
- TouchableDistance:可觸控表面可以與其互動的最大距離
- 視覺效果:用來呈現手指尖視覺效果的遊戲物件,預設 (手指上的環形) 。
- 線條:選擇性線條,從手指尖繪製到使用中的輸入介面。
- Poke Layer Masks - LayerMasks 的優先順序陣列,用來判斷指標可以與其互動的可能 GameObject,以及要嘗試的互動順序。 請注意,GameObject 也必須有
NearInteractionTouchable
元件,才能與 poke 指標互動。
SpherePointer
SpherePointer會使用UnityEngine.Physics.OverlapSphere來識別最接近 NearInteractionGrabbable
的互動物件,這適用于類似 的 ManipulationHandler
「可抓取」輸入。 類似于 PokePointer
/NearInteractionTouchable
功能組,若要與 Sphere 指標互動,遊戲物件必須包含腳本的 NearInteractionGrabbable
元件。
有用的 Sphere 指標屬性:
- 球體轉換半徑:用來查詢可抓取物件的球體半徑。
- 接近物件邊界:在 Sphere 轉換半徑頂端的距離,用來查詢物件是否接近指標。 接近物件偵測半徑總計為 Sphere 轉換半徑 + 接近物件邊界
- 近物件磁區角度:指標正向軸的角度,用於查詢鄰近物件。
IsNearObject
讓查詢函式像圓錐。 根據預設,這會設定為 66 度以符合 Hololens 2 行為
- Near Object Smoothing Factor:Near Object Detection 的 Smoothing Factor。 如果在 Near Object Radius 中偵測到物件,則查詢的半徑會變成 Near Object Radius * (1 + Near Object Smoothing Factor) 以減少敏感度,讓物件更難離開偵測範圍。
- 擷取圖層遮罩 - LayerMasks 的優先順序陣列,用來判斷指標可以與其互動的可能 GameObject,以及要嘗試的互動順序。 請注意,GameObject 也必須有
NearInteractionGrabbable
,才能與 SpherePointer 互動。注意
空間感知層會在 MRTK 所提供的預設 GrabPointer 預製專案中停用。 這是為了降低執行球體重迭查詢與空間網格的效能影響。 您可以修改 GrabPointer 預製專案來啟用此功能。
- 忽略不在 FOV 中的碰撞器 - 是否忽略可能接近指標的碰撞器,但實際上不在視覺 FOV 中。 這可以防止意外抓取,而且當您可能接近可抓取但看不到時,手部光線就會開啟。 Visual FOV是透過圓錐來定義,而不是基於效能考慮的一般 Frustum。 這個圓錐的置中和方向與相機的長條圖相同,其半徑等於半形顯示高度 (或垂直 FOV) 。
Teleport 指標
TeleportPointer
會在採取動作 (時引發遠端傳送要求,也就是按下) 來移動使用者。ParabolicTeleportPointer
會在採取動作 (時引發遠端傳送要求,亦即會以參數線光線廣播按下) 遠端埠按鈕,以移動使用者。
混合實境平臺的指標支援
下表詳細說明通常用於 MRTK 中通用平臺的指標類型。 注意:可以將不同的指標類型新增至這些平臺。 例如,您可以將 Poke 指標或 Sphere 指標新增至 VR。 此外,具有遊戲台的 VR 裝置可以使用 GGV 指標。
Pointer | OpenVR | Windows Mixed Reality | HoloLens 1 | HoloLens 2 |
---|---|---|---|---|
ShellHandRayPointer | 有效 | 有效 | 有效 | |
TeleportPointer | 有效 | 有效 | ||
GGVPointer | 有效 | |||
SpherePointer | 有效 | |||
PokePointer | 有效 |
透過程式碼的指標互動
指標事件介面
實作下列一或多個介面的 MonoBehaviours,並使用 指派給 GameObject Collider
,將會收到相關介面所定義的指標互動事件。
事件 | 描述 | 處理常式 |
---|---|---|
焦點變更之前/焦點已變更 | 每次指標變更焦點時,遊戲物件都會失去焦點,以及每次指標變更焦點時都會取得它。 | IMixedRealityFocusChangedHandler |
焦點輸入/結束 | 在遊戲物件上引發,當第一個指標進入時取得焦點,並在最後一個指標離開焦點時失去焦點。 | IMixedRealityFocusHandler |
指標向下/拖曳/向上/按一下 | 引發至報表指標按下、拖放和放開。 | IMixedRealityPointerHandler |
觸控已啟動/更新/已完成 | 由觸控感知指標引發,例如 PokePointer 報告觸控活動。 |
IMixedRealityTouchHandler |
注意
IMixedRealityFocusChangedHandler
和 IMixedRealityFocusHandler
應該在引發的物件中處理。 全域接收焦點事件,但與其他輸入事件不同,全域事件處理常式不會封鎖根據焦點接收事件, (全域處理常式和焦點) 的對應物件都會接收事件。
作用中的指標輸入事件
MRTK 輸入系統會以與 一般輸入事件類似的方式辨識和處理指標輸入事件。 指標輸入事件的差異,只是由引發輸入事件的指標以及任何全域輸入處理常式,以焦點方式處理 GameObject。 一般輸入事件是由 GameObjects 處理,以焦點處理所有作用中的指標。
- MRTK 輸入系統可辨識輸入事件已發生
- MRTK 輸入系統會將輸入事件的相關介面函式引發至所有已註冊的全域輸入處理常式
- 輸入系統會決定引發事件的指標的 GameObject 焦點
- 輸入系統會利用 Unity 的事件系統 ,針對焦點 GameObject 上的所有相符元件引發相關的介面函式
- 如果輸入事件在任何時間點 標示為已使用,進程將會結束,而且不會再收到 GameObjects 回呼。
- 範例:實作介面
IMixedRealityFocusHandler
的元件將會搜尋 GameObject 取得或失去焦點 - 注意:如果目前 GameObject 上找不到符合所需介面的元件,Unity 事件系統將會反升為搜尋父 GameObject。
- 範例:實作介面
- 如果未註冊任何全域輸入處理常式,且找不到具有相符元件/介面的 GameObject,則輸入系統會呼叫每個後援已註冊的輸入處理常式
範例
以下是範例腳本,會在指標取得或離開焦點或指標選取物件時,變更附加轉譯器的色彩。
public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler, IMixedRealityPointerHandler
{
private Color color_IdleState = Color.cyan;
private Color color_OnHover = Color.white;
private Color color_OnSelect = Color.blue;
private Material material;
private void Awake()
{
material = GetComponent<Renderer>().material;
}
void IMixedRealityFocusHandler.OnFocusEnter(FocusEventData eventData)
{
material.color = color_OnHover;
}
void IMixedRealityFocusHandler.OnFocusExit(FocusEventData eventData)
{
material.color = color_IdleState;
}
void IMixedRealityPointerHandler.OnPointerDown(
MixedRealityPointerEventData eventData) { }
void IMixedRealityPointerHandler.OnPointerDragged(
MixedRealityPointerEventData eventData) { }
void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
{
material.color = color_OnSelect;
}
}
查詢指標
您可以迴圈查看可用的輸入來源,以收集目前使用的所有指標 (,也就是控制器和可用的輸入) ,以探索哪些指標已附加至這些指標。
var pointers = new HashSet<IMixedRealityPointer>();
// Find all valid pointers
foreach (var inputSource in CoreServices.InputSystem.DetectedInputSources)
{
foreach (var pointer in inputSource.Pointers)
{
if (pointer.IsInteractionEnabled && !pointers.Contains(pointer))
{
pointers.Add(pointer);
}
}
}
主要指標
開發人員可以訂閱 FocusProviders PrimaryPointerChanged 事件,以在焦點中的主要指標變更時收到通知。 這非常實用,可識別使用者目前是否透過注視或手部光線或其他輸入來源來與場景互動。
private void OnEnable()
{
var focusProvider = CoreServices.InputSystem?.FocusProvider;
focusProvider?.SubscribeToPrimaryPointerChanged(OnPrimaryPointerChanged, true);
}
private void OnPrimaryPointerChanged(IMixedRealityPointer oldPointer, IMixedRealityPointer newPointer)
{
...
}
private void OnDisable()
{
var focusProvider = CoreServices.InputSystem?.FocusProvider;
focusProvider?.UnsubscribeFromPrimaryPointerChanged(OnPrimaryPointerChanged);
// This flushes out the current primary pointer
OnPrimaryPointerChanged(null, null);
}
PrimaryPointerExample
(Assets/MRTK/Examples/Demos/Input/Scenes/PrimaryPointer) 場景示範如何使用 PrimaryPointerChangedHandler
來回應新的主要指標。
指標結果
指標 Result
屬性包含用來判斷具有焦點之物件的場景查詢目前結果。 針對光線廣播指標,就像針對動作控制器、注視輸入和手部光線所建立的指標一樣,它會包含光線廣播點擊的位置和一般。
private void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
{
var result = eventData.Pointer.Result;
var spawnPosition = result.Details.Point;
var spawnRotation = Quaternion.LookRotation(result.Details.Normal);
Instantiate(MyPrefab, spawnPosition, spawnRotation);
}
PointerResultExample
場景 (Assets/MRTK/Examples/Demos/Input/Scenes/PointerResult/PointerResultExample.unity) 示範如何使用指標 Result
在點擊位置繁衍物件。
停用指標
例如,若要開啟和停用指標 (,若要停用手部光線) ,請透過 PointerUtils
設定 PointerBehavior
指定指標類型的 。
// Disable the hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);
// Disable hand rays for the right hand only
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Right);
// Disable the gaze pointer
PointerUtils.SetGazePointerBehavior(PointerBehavior.AlwaysOff);
// Set the behavior to match HoloLens 1
// Note, if on HoloLens 2, you must configure your pointer profile to make the GGV pointer show up for articulated hands.
public void SetHoloLens1()
{
PointerUtils.SetPokePointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
PointerUtils.SetGrabPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
PointerUtils.SetRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
PointerUtils.SetGGVBehavior(PointerBehavior.Default);
}
如需更多範例,請參閱 PointerUtils
和 TurnPointersOnOff
。
透過編輯器的指標互動
針對 所 IMixedRealityPointerHandler
處理的指標事件,MRTK 提供元件形式的 PointerHandler
進一步便利性,這可讓指標事件透過 Unity 事件直接處理。
指標範圍
遠方指標的設定會限制其光線傳播的程度,並與場景中的其他物件互動。 根據預設,此值會設定為 10 公尺。 已選擇這個值,以與 HoloLens 殼層的行為保持一致。
您可以藉由更新 DefaultControllerPointer
預製專案的 ShellHandRayPointer
元件欄位來變更:
指標範圍 - 這會控制指標將與其互動的最大距離。
預設指標範圍 - 這會控制指標未與任何專案互動時,將呈現的指標光線/線條長度。