Dela via


Indatahändelser – MRTK2

I listan nedan beskrivs alla tillgängliga gränssnitt för indatahändelser som ska implementeras av en anpassad MonoBehaviour-komponent. Dessa gränssnitt anropas av MRTK-indatasystemet för att hantera anpassad applogik baserat på interaktion med användarindata. Pekarens indatahändelser hanteras något annorlunda än standardindatahändelsetyperna nedan.

Viktigt

Som standard får ett skript endast indatahändelser om det är GameObject i fokus med en pekare eller överordnad för ett GameObject i fokus.

Hanterare Händelser Description
IMixedRealitySourceStateHandler Källan har identifierats/förlorats Utlöses när en indatakälla identifieras/förloras, till exempel när en ledad hand identifieras eller tappas bort.
IMixedRealitySourcePoseHandler Källpositionen har ändrats Aktiveras vid ändringar i källpositionen. Källställningen representerar den allmänna attityden för indatakällan. Specifika poser, till exempel greppet eller pekaren i en sex DOF-kontrollant, kan hämtas via IMixedRealityInputHandler<MixedRealityPose>.
IMixedRealityInputHandler Indata nedåt/uppåt Aktiveras vid ändringar av binära indata som knappar.
IMixedRealityInputHandler<T> Indata har ändrats Aktiveras vid ändringar av indata för den angivna typen. T kan använda följande värden:
- float (t.ex. returnerar analog utlösare)
- Vector2 (returnerar t.ex. gamepad-tumsticksriktning)
- Vector3 (t.ex. returposition för spårad enhet)
- Quaternion (t.ex. returnerar orienteringen för den spårade enheten)
- MixedRealityPose (t.ex. returnerar fullständigt spårad enhet)
IMixedRealitySpeechHandler Nyckelordet Tal känns igen Aktiverad vid igenkänning av ett av nyckelorden som konfigurerats i talkommandoprofilen.
IMixedRealityDictationHandler Diktamen
Hypotesen
Resultat
Klart
Fel
Upphöjt av dikteringssystem för att rapportera resultatet av en dikteringssession.
IMixedRealityGestureHandler Gesthändelser på:
Börjat
Uppdaterad
Slutförd
Avbrutna
Aktiverad vid gestidentifiering.
IMixedRealityGestureHandler<T> Gesten har uppdaterats/slutförts Aktiverad vid identifiering av gester som innehåller ytterligare data av den angivna typen. Se gesthändelser för mer information om möjliga värden för T.
IMixedRealityHandJointHandler Hand joints uppdaterad Upphöjt av ledade handkontrollanter när handfogarna uppdateras.
IMixedRealityHandMeshHandler Handnät uppdaterat Upphöjt av ledade handkontrollanter när ett handnät uppdateras.
IMixedRealityInputActionHandler Åtgärden startades/avslutades Höj för att ange åtgärdens start och slut för indata som har mappats till åtgärder.

Indatahändelser i praktiken

På skriptnivå kan indatahändelser användas genom att implementera ett av de händelsehanterargränssnitt som visas i tabellen ovan. När en indatahändelse utlöses via en användarinteraktion sker följande:

  1. MRTK-indatasystemet identifierar att en indatahändelse har inträffat.
  2. MRTK-indatasystemet utlöser den relevanta gränssnittsfunktionen för indatahändelsen till alla registrerade globala indatahanterare
  3. För varje aktiv pekare som registrerats med indatasystemet:
    1. Indatasystemet avgör vilket GameObject som är i fokus för den aktuella pekaren.
    2. Indatasystemet använder Unitys händelsesystem för att utlösa relevant gränssnittsfunktion för alla matchande komponenter på det fokuserade GameObject.
    3. Om en indatahändelse har markerats som använd avslutas processen och inga ytterligare GameObjects får återanrop.
      • Exempel: Komponenter som implementerar gränssnittet IMixedRealitySpeechHandler genomsöks när ett talkommando identifieras.
      • Obs! Unity-händelsesystemet bubblar upp för att söka i det överordnade GameObject om inga komponenter som matchar önskat gränssnitt hittas i det aktuella GameObject.
  4. Om inga globala indatahanterare har registrerats och inget GameObject hittas med en matchande komponent/gränssnitt anropar indatasystemet varje fallback-registrerad indatahanterare

Anteckning

Pekarens indatahändelser hanteras på ett något annorlunda sätt än de gränssnitt för indatahändelser som anges ovan. I synnerhet hanteras pekarindatahändelser endast av GameObject i fokus av pekaren som utlöste indatahändelsen – samt eventuella globala indatahanterare. Vanliga indatahändelser hanteras av GameObjects i fokus för alla aktiva pekare.

Exempel på indatahändelsegränssnitt

Koden nedan visar hur gränssnittet används IMixedRealitySpeechHandler . När användaren säger orden "mindre" eller "större" samtidigt som de fokuserar på ett GameObject med den här ShowHideSpeechHandler klassen skalar GameObject sig själv med hälften eller dubbelt så mycket.

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;
        }
    }
}

Anteckning

IMixedRealitySpeechHandler indatahändelser kräver att önskade nyckelord är förregistrerade i MRTK-talkommandoprofilen.

Registrera dig för globala indatahändelser

Om du vill skapa en komponent som lyssnar efter globala indatahändelser, utan hänsyn till vad GameObject kan vara i fokus, måste en komponent registrera sig med indatasystemet. När de har registrerats får alla instanser av denna MonoBehaviour indatahändelser tillsammans med alla GameObject(er) som för närvarande är i fokus och andra globala registrerade lyssnare.

Om en indatahändelse har markerats som använd får globala registrerade hanterare fortfarande återanrop. Inga fokuserade GameObjects kommer dock att ta emot händelsen.

Exempel på global indataregistrering

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);
        }
    }
}

Registrera dig för återställningsindatahändelser

Reservindatahanterare liknar registrerade globala indatahanterare men behandlas som en sista utväg för hantering av indatahändelser. Endast om inga globala indatahanterare hittades och inga GameObjects är i fokus kommer reservindatahanterare att utnyttjas.

Exempel på reservindatahanterare

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)
    {
        ...
    }
}

Stoppa indatahändelser

Varje gränssnitt för indatahändelser tillhandahåller ett BaseInputEventData dataobjekt som en parameter för varje funktion i gränssnittet. Det här händelsedataobjektet sträcker sig från Unitys eget AbstractEventData.

För att förhindra att en indatahändelse sprids genom dess körning enligt beskrivningen kan en komponent anropa AbstractEventData.Use() för att markera händelsen som använd. Detta hindrar andra GameObjects från att ta emot den aktuella indatahändelsen, med undantag för globala indatahanterare.

Anteckning

En komponent som anropar Use() metoden hindrar andra GameObjects från att ta emot den. Andra komponenter i det aktuella GameObject tar dock fortfarande emot indatahändelsen och utlöser alla relaterade gränssnittsfunktioner.

Se även