如何新增近互動功能 — MRTK2

近距離互動會以觸控和抓取的形式出現。 PokePointerSpherePointer會分別以指標事件的形式引發觸控和抓取事件。

需要三個主要步驟,才能接聽特定 GameObject 上的觸控和/或抓取輸入事件。

  1. 請確定已在主要 MRTK 組態設定檔中註冊相關的指標。
  2. 確定所需的 GameObject 具有適當的 抓取觸控 腳本元件和 Unity Collider
  3. 在附加的腳本上實作輸入處理常式介面,以接聽 抓取觸控 事件所需的 GameObject。

新增抓取互動

  1. 請確定 SpherePointer 已在 MRTK 指標設定檔中註冊。

    預設 MRTK 設定檔和預設HoloLens 2設定檔已經包含SpherePointer。 您可以選取 MRTK 組態設定檔並流覽至[輸入>指標指標>選項] 來確認將建立 SpherePointer。 預設 GrabPointer 預製專案 (Assets/MRTK/SDK/Features/UX/Prefabs/Pointers) 應列在 控制器類型「已表達的手部」。 只要自訂預製專案實 SpherePointer 作 類別即可使用。

    Grab Pointer Profile Example

    預設抓取指標會查詢抓取點周圍的附近物件,以符合預設 Hololens 2 介面。

    Conical Grab Pointer

  2. 在應該可抓取的 GameObject 上,新增 NearInteractionGrabbable 和 碰撞器。

    請確定 GameObject 的圖層位於可抓取的圖層上。 根據預設, 除了空間感知忽略 Raycast 以外 ,所有圖層都是可抓取的。 藉由檢查您的 GrabPointer預製專案中的抓取層遮罩,查看哪些圖層可抓取。

  3. 在 GameObject 或其上階的其中一個上階上,新增實作 介面的 IMixedRealityPointerHandler 腳本元件。 任何具有 NearInteractionGrabbable 的物件上階也可以接收指標事件。

抓取程式碼範例

以下是會在事件是觸控或抓取時列印的腳本。 在相關的 IMixedRealityPointerHandler 介面函式中,可以查看透過 MixedRealityPointerEventData 觸發該事件的指標類型。 如果指標是 SpherePointer,互動就是抓取。

public class PrintPointerEvents : MonoBehaviour, IMixedRealityPointerHandler
{
    public void OnPointerDown(MixedRealityPointerEventData eventData)
    {
        if (eventData.Pointer is SpherePointer)
        {
            Debug.Log($"Grab start from {eventData.Pointer.PointerName}");
        }
        if (eventData.Pointer is PokePointer)
        {
            Debug.Log($"Touch start from {eventData.Pointer.PointerName}");
        }
    }

    public void OnPointerClicked(MixedRealityPointerEventData eventData) {}
    public void OnPointerDragged(MixedRealityPointerEventData eventData) {}
    public void OnPointerUp(MixedRealityPointerEventData eventData) {}
}

新增觸控互動

在 UnityUI 元素上新增觸控互動的程式與 vanilla 3D GameObjects 的程式不同。 您可以跳至下一節 Unity UI,以啟用 Unity UI 元件。

不過,對於 這兩 種類型的 UX 元素,請確定 PokePointer 已在 MRTK 指標設定檔中註冊。

預設 MRTK 設定檔和預設HoloLens 2設定檔已經包含PokePointer。 您可以選取 MRTK 組態設定檔並流覽至[輸入>指標指標>選項] 來確認將建立 PokePointer。 預設 PokePointer (Assets/MRTK/SDK/Features/UX/Prefabs/Pointers) 預製專案應列在 [控制器類型 ] 的 [清楚手部]。 只要自訂預製專案實 PokePointer 作 類別即可使用。

Poke Pointer Profile Example

3D GameObjects

有兩種不同的方式可將觸控互動新增至 3D GameObjects,取決於您的 3d 物件是否應該只有單一可觸控平面,或是否應該根據其整個碰撞器進行觸控。 第一種方式通常是在具有 BoxColliders 的物件上,其中希望只有碰撞器的單一臉部會回應觸控事件。 另一個是針對需要根據碰撞器從任何方向接觸的物件。

單一臉部觸控

這適用于只需要觸控單一臉部的情況。 此選項假設遊戲物件具有 BoxCollider。 這可以搭配非 BoxCollider 物件使用,在此情況下,'Bounds' 和 'Local Center' 屬性會手動設定為設定可觸控平面 (亦即界限應設定為非零零值) 。

  1. 在應該可觸控的 GameObject 上,新增 BoxCollider 和 [ NearInteractionTouchable ] (xref:Microsoft.MixedReality.Toolkit.Input.NearInteractionTouchable) 元件。

    1. 如果使用下列元件腳本中的 [ IMixedRealityTouchHandler ] (xref:Microsoft.MixedReality.Toolkit.Input.IMixedRealityTouchHandler) 介面,請將[事件] 設定為 [接收] 。

    2. 按一下 [修正界限 ] 和 [修正中心]

    NearInteractionTouchable Setup

  2. 在該物件或其上階的其中一個上階上,新增實作 的腳本元件IMixedRealityTouchHandler 介面。 任何具有 [ NearInteractionTouchable ] (xref:Microsoft.MixedReality.Toolkit.Input.NearInteractionTouchable) 的物件上階,也能夠接收指標事件。

注意

在已選取 NearInteractionTouchable GameObject 的編輯器場景檢視中,請注意白色外框方塊和箭號。 箭號指向可觸控的「前端」。 碰撞只會從該方向觸碰。 若要讓碰撞器從所有方向觸碰,請參閱 任意碰撞器觸控的一節。 NearInteractionTouchable Gizmos

任意碰撞器觸控

這很適合用來讓遊戲物件沿著整個碰撞器臉部接觸的情況。 例如,這可以用來啟用物件與 SphereCollider 的觸控互動,其中整個碰撞器必須可觸控。

  1. 在應該可觸控的 GameObject 上,新增碰撞器和 [ NearInteractionTouchableVolume ] (xref:Microsoft.MixedReality.Toolkit.Input.NearInteractionTouchableVolume) 元件。

    1. 如果使用下列元件腳本中的 [ IMixedRealityTouchHandler ] (xref:Microsoft.MixedReality.Toolkit.Input.IMixedRealityTouchHandler) 介面,請將[事件] 設定為 [接收] 。
  2. 在該物件或其上階的其中一個上階上,新增實作 的腳本元件IMixedRealityTouchHandler 介面。 任何具有 [ NearInteractionTouchable ] (xref:Microsoft.MixedReality.Toolkit.Input.NearInteractionTouchable) 的物件上階,也能夠接收指標事件。

Unity UI

  1. 新增/確定場景中有 UnityUI 畫布

  2. 在應該可觸控的 GameObject 上,新增 NearInteractionTouchableUnityUI 元件。

    1. 如果使用下列元件腳本中的 介面, IMixedRealityTouchHandler 請將[事件] 設定為 [接收] 為[觸控]。
  3. 在該物件或其上階的其中一個上階上,新增實作 介面的 IMixedRealityTouchHandler 腳本元件。 具有 NearInteractionTouchableUnityUI 的任何物件上階也都可以接收指標事件。

重要

如果物件位於重迭的畫布物件上,物件可能無法如預期般運作。 為了確保一致的行為,請勿重迭場景中的畫布物件。

重要

NearInteractionTouchable 腳本元件上,[ 要接收的事件 ] 屬性有兩個選項: 指標觸控如果在元件腳本中使用 IMixedRealityPointerHandler 回應/處理輸入事件的介面,請將[事件] 設定IMixedRealityTouchHandler 為 [接收] 為[指標]。

觸控程式碼範例

下列程式碼示範 MonoBehaviour,可附加至具有 NearInteractionTouchable 變體元件的 GameObject,並回應觸控輸入事件。

public class TouchEventsExample : MonoBehaviour, IMixedRealityTouchHandler
{
    public void OnTouchStarted(HandTrackingInputEventData eventData)
    {
        string ptrName = eventData.Pointer.PointerName;
        Debug.Log($"Touch started from {ptrName}");
    }
    public void OnTouchCompleted(HandTrackingInputEventData eventData) {}
    public void OnTouchUpdated(HandTrackingInputEventData eventData) { }
}

近距離互動腳本範例

觸控事件

此範例會建立 Cube、使其可觸控,以及變更觸控的色彩。

public static void MakeChangeColorOnTouch(GameObject target)
{
    // Add and configure the touchable
    var touchable = target.AddComponent<NearInteractionTouchableVolume>();
    touchable.EventsToReceive = TouchableEventType.Pointer;

    var material = target.GetComponent<Renderer>().material;
    // Change color on pointer down and up
    var pointerHandler = target.AddComponent<PointerHandler>();
    pointerHandler.OnPointerDown.AddListener((e) => material.color = Color.green);
    pointerHandler.OnPointerUp.AddListener((e) => material.color = Color.magenta);
}

抓取事件

下列範例示範如何讓 GameObject 可拖曳。 假設遊戲物件上有一個碰撞器。

public static void MakeNearDraggable(GameObject target)
{
    // Instantiate and add grabbable
    target.AddComponent<NearInteractionGrabbable>();

    // Add ability to drag by re-parenting to pointer object on pointer down
    var pointerHandler = target.AddComponent<PointerHandler>();
    pointerHandler.OnPointerDown.AddListener((e) =>
    {
        if (e.Pointer is SpherePointer)
        {
            target.transform.parent = ((SpherePointer)(e.Pointer)).transform;
        }
    });
    pointerHandler.OnPointerUp.AddListener((e) =>
    {
        if (e.Pointer is SpherePointer)
        {
            target.transform.parent = null;
        }
    });
}

實用的 API

另請參閱