輸入事件 — MRTK2

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

重要

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

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

另請參閱