輸入事件 — MRTK2

下列清單概述自訂 MonoBehaviour 元件要實作的所有可用輸入事件介面。 MRTK 輸入系統會呼叫這些介面,以根據使用者輸入互動來處理自訂應用程式邏輯。 指標輸入事件 處理方式與下列標準輸入事件種類稍有不同。

重要

根據預設,只有當腳本是焦點中 GameObject 的指標或父代時,腳本才會收到輸入事件。

處理常式 事件 描述
IMixedRealitySourceStateHandler 偵測到來源/遺失 當偵測到/遺失輸入來源時引發,例如偵測到清楚的手部或遺失追蹤時。
IMixedRealitySourcePoseHandler 來源姿勢已變更 在來源造成變更時引發。 來源姿勢代表輸入來源的一般姿勢。 您可以透過 IMixedRealityInputHandler<MixedRealityPose> 取得特定姿勢,例如六個 DOF 控制器中的底框或指標姿勢。
IMixedRealityInputHandler 輸入向下/向上輸入 在按鈕之類的二進位輸入變更時引發。
IMixedRealityInputHandler<T> 輸入已變更 在指定型別的輸入變更時引發。 T 可以接受下列值:
- float (,例如傳回類比觸發程式)
- Vector2 (例如傳回遊戲台搖桿方向)
- Vector3 (例如追蹤裝置) 的傳回位置
- 四元數 (例如傳回追蹤裝置的方向)
- MixedRealityPose (例如傳回完整追蹤的裝置)
IMixedRealitySpeechHandler 辨識語音關鍵字 在辨識語音 命令設定檔中設定的其中一個關鍵字時引發。
IMixedRealityDictationHandler 聽寫
假設
結果
完成
錯誤
由聽寫系統引發,以報告聽寫會話的結果。
IMixedRealityGestureHandler 開啟的手勢事件:
已開始
已更新
已完成
已取消
在手勢偵測時引發。
IMixedRealityGestureHandler<T> 手勢已更新/已完成 在偵測包含指定類型其他資料的手勢時引發。 如需T可能值的詳細資料,請參閱手勢事件
IMixedRealityHandJointHandler 已更新手部接合 在更新手部接合時,由清楚表達的手部控制器所引發。
IMixedRealityHandMeshHandler 已更新手部網格 在更新手部網格時,由清楚表達的手部控制器所引發。
IMixedRealityInputActionHandler 動作已啟動/結束 引發 ,表示對應至動作之輸入的動作開始和結束。

作用中的輸入事件

在腳本層級,您可以實作上表所示的其中一個事件處理常式介面來取用輸入事件。 當輸入事件透過使用者互動引發時,會發生下列動作:

  1. MRTK 輸入系統可辨識已發生輸入事件。
  2. MRTK 輸入系統會將輸入事件的相關介面函式引發至所有 已註冊的全域輸入處理常式
  3. 針對向輸入系統註冊的每個作用中指標:
    1. 輸入系統會決定哪些 GameObject 是目前指標的焦點。
    2. 輸入系統會利用 Unity 的事件系統 ,針對焦點 GameObject 上的所有相符元件引發相關的介面函式。
    3. 如果輸入事件在任何時間點 標示為已使用,進程將會結束,而且不會再收到 GameObjects 回呼。
      • 範例:辨識語音命令時,會搜尋實作介面 IMixedRealitySpeechHandler 的元件。
      • 注意:如果目前 GameObject 上找不到符合所需介面的元件,Unity 事件系統將會反升至搜尋父 GameObject。
  4. 如果未註冊任何全域輸入處理常式,而且找不到具有相符元件/介面的 GameObject,則輸入系統會呼叫每個後援註冊的輸入處理常式

注意

指標輸入事件 會以與上面所列的輸入事件介面略有不同的方式來處理。 特別是,指標輸入事件只會由引發輸入事件的指標以及任何全域輸入處理常式來處理焦點中的 GameObject。 一般輸入事件是由所有作用中指標的 GameObjects 處理。

輸入事件介面範例

下列程式碼示範如何使用 IMixedRealitySpeechHandler 介面。 當使用者以這個 ShowHideSpeechHandler 類別將焦點放在 GameObject 時,說出「較小」或「較大」這個字時,GameObject 將自行調整為一半或兩倍。

public class ShowHideSpeechHandler : MonoBehaviour, IMixedRealitySpeechHandler
{
    ...

    void IMixedRealitySpeechHandler.OnSpeechKeywordRecognized(SpeechEventData eventData)
    {
        if (eventData.Command.Keyword == "smaller")
        {
            transform.localScale *= 0.5f;
        }
        else if (eventData.Command.Keyword == "bigger")
        {
            transform.localScale *= 2.0f;
        }
    }
}

注意

IMixedRealitySpeechHandler 輸入事件要求在 MRTK 語音命令設定檔中預先註冊所需的關鍵字。

註冊全域輸入事件

若要建立可接聽全域輸入事件的元件,忽略 GameObject 可能處於焦點,元件必須向輸入系統註冊本身。 註冊之後,此 MonoBehaviour 的任何實例都會接收輸入事件,以及目前處於焦點的 GameObject (s) 和其他全域註冊接聽程式。

如果輸入事件標示 為已使用,全域註冊的處理常式仍會全部接收回呼。 不過,沒有焦點的 GameObjects 會收到事件。

全域輸入註冊範例

public class GlobalHandListenerExample : MonoBehaviour,
    IMixedRealitySourceStateHandler, // Handle source detected and lost
    IMixedRealityHandJointHandler // handle joint position updates for hands
{
    private void OnEnable()
    {
        // Instruct Input System that we would like to receive all input events of type
        // IMixedRealitySourceStateHandler and IMixedRealityHandJointHandler
        CoreServices.InputSystem?.RegisterHandler<IMixedRealitySourceStateHandler>(this);
        CoreServices.InputSystem?.RegisterHandler<IMixedRealityHandJointHandler>(this);
    }

    private void OnDisable()
    {
        // This component is being destroyed
        // Instruct the Input System to disregard us for input event handling
        CoreServices.InputSystem?.UnregisterHandler<IMixedRealitySourceStateHandler>(this);
        CoreServices.InputSystem?.UnregisterHandler<IMixedRealityHandJointHandler>(this);
    }

    // IMixedRealitySourceStateHandler interface
    public void OnSourceDetected(SourceStateEventData eventData)
    {
        var hand = eventData.Controller as IMixedRealityHand;

        // Only react to articulated hand input sources
        if (hand != null)
        {
            Debug.Log("Source detected: " + hand.ControllerHandedness);
        }
    }

    public void OnSourceLost(SourceStateEventData eventData)
    {
        var hand = eventData.Controller as IMixedRealityHand;

        // Only react to articulated hand input sources
        if (hand != null)
        {
            Debug.Log("Source lost: " + hand.ControllerHandedness);
        }
    }

    public void OnHandJointsUpdated(
                InputEventData<IDictionary<TrackedHandJoint, MixedRealityPose>> eventData)
    {
        MixedRealityPose palmPose;
        if (eventData.InputData.TryGetValue(TrackedHandJoint.Palm, out palmPose))
        {
            Debug.Log("Hand Joint Palm Updated: " + palmPose.Position);
        }
    }
}

註冊後援輸入事件

後援輸入處理常式類似于已註冊的全域輸入處理常式,但會被視為輸入事件處理的最後手段。 只有在找不到全域輸入處理常式且沒有 GameObjects 處於焦點時,才會利用後援輸入處理常式。

後援輸入處理常式範例

public class GlobalHandListenerExample : MonoBehaviour,
    IMixedRealitySourceStateHandler // Handle source detected and lost
{
    private void OnEnable()
    {
        CoreServices.InputSystem?.PushFallbackInputHandler(this);
    }

    private void OnDisable()
    {
        CoreServices.InputSystem?.PopFallbackInputHandler();
    }

    // IMixedRealitySourceStateHandler interface
    public void OnSourceDetected(SourceStateEventData eventData)
    {
        ...
    }

    public void OnSourceLost(SourceStateEventData eventData)
    {
        ...
    }
}

如何停止輸入事件

每個輸入事件介面都會 BaseInputEventData 提供資料物件做為介面上每個函式的參數。 這個事件資料物件會從 Unity 自己的 AbstractEventData 擴充。

為了停止輸入事件以 概述的方式傳播其執行,元件可以呼叫 AbstractEventData.Use() 來將事件標示為已使用。 這將會停止任何其他 GameObject 接收目前的輸入事件,但全域輸入處理常式除外。

注意

呼叫 方法的 Use() 元件會停止其他 GameObjects 接收它。 不過,目前 GameObject 上的其他元件仍會收到輸入事件,並引發任何相關的介面函式。

另請參閱