Interaktor-Architektur — MRTK3

MRTK baut auf den Interaktoren auf, die das XR Interaction Toolkit von Unity bietet. Mixed-Reality-Funktionen wie die artikulierte Handverfolgung, der Blick und Pinch erfordern aufwendigere Interaktoren als die, die standardmäßig mit XRI bereitgestellt werden. MRTK definiert neue Interaktionsschnittstellen, kategorisiert im Allgemeinen durch die Eingabemodalitäten und entsprechende Implementierungen.

Zusammenfassung und Überprüfung

Wir empfehlen für Entwickler, die XRI noch nicht kennen, dass Sie zunächst die Dokumentation zur XRI-Architektur von Unity lesen. MRTK-Interaktoren sind Unterklassen bestehender XRI-Interaktoren oder Implementierungen der XRI-Interaktor-Schnittstellen. Weitere Informationen finden Sie in der Unity-Dokumentation zur Interaktor-Architektur, die auch für MRTK gilt.

Gute Bürger von XRI

Die benutzerdefinierten MRTK-Interaktoren verhalten sich in Bezug auf die standardmäßigen XRI-Interaktorschnittstellen gut; aus der Perspektive von XRI-Systemen sind sie von "Vanille"-Interaktoren nicht zu unterscheiden. Das gilt auch umgekehrt: Wenn Sie in MRTK fortgeschrittene interaktive Elemente erstellen, funktionieren die standardmäßigen XRI-Interaktoren weiterhin für einfache Hover- und Select-Funktionen. Es ist Teil der MRTK-Bemühungen, vollständig mit bestehenden XRI-Projekten kompatibel zu sein. Wenn Sie eine XRI-Anwendung haben, funktionieren MRTK-Interaktionselemente und UI-Steuerelemente mit Ihrem vorhandenen „Vanilla“-XRI-Setup.

Abstraktion der Eingabemodalitäten

Das Eingabegerät, der die Interaktion ausführende Interaktor und die von ihnen generierten Interaktionsereignisse sind in XRI alle architektonisch isoliert. Diese Isolation ist entscheidend für die Eingabeabstraktionsstrategie in MRTK3 und ermöglicht es uns, plattformübergreifende und geräteübergreifende Interaktionen zu schreiben, die in allen Kontexten gut funktionieren.

Ab MRTK v2 gibt es einen gemeinsamen Instinkt, Interaktionen zu codieren, die für einen bestimmten Eingabetyp oder ein bestimmtes Gerät spezifisch sind. Viele Entwickler sind daran gewöhnt, Interaktionen zu schreiben, die speziell auf einen nahen Griff, einen fernen Strahl oder einen anderen spezifischen Eingabetyp reagieren.

Während MRTK3 immer noch die Disambiguierung und Erkennung einzelner Eingabemodi ermöglicht, schränkt die Hartcodierung von Interaktionen für bestimmte individuelle Eingabetypen künstlich ein und verringert die Flexibilität Ihrer Interaktionen. Weitere Informationen dazu finden Sie in der interagierbaren Architekturdokumentation, aber der Schlüssel für Interaktoren besteht darin, dass sie im Allgemeinen nicht 1:1 mit Eingabegeräten zuordnen müssen.

AttachTransform und Inversion von Steuerelementen

Vieles, was MRTK v2 in "Bewegungslogik" als Teil von ObjectManipulator, Slider, usw. getan hat, liegt jetzt in der Verantwortung des Interaktors selbst. Der Interaktor steuert nun seine AttachTransform, um zu definieren, wie sich eine bestimmte Art von Manipulation verhält. Man muss keine komplexe Interaktionslogik mehr auf dem interaktiven Objekt schreiben, die sich zwischen den Eingabemodalitäten unterscheidet; Stattdessen kann Ihre einheitliche Manipulationslogik die attachTransform"Posen" befolgen, unabhängig der Eingabemodalitäten oder des Geräts, das sie antreibt.

So befindet sich z. B. ein GrabInteractor's attachTransform auf dem Griffpunkt auf dem Hand-/Controller. Ein XRRayInteractor's attachTransform befindet sich am Zugriffspunkt am Ende des Strahls. Die CanvasProxyInteractor's attachTransform befindet sich überall, wo die Maus geklickt hat. Bei all diesen unterschiedlichen Interaktoren muss sich das interaktive Objekt nicht um den Typ des Interaktors kümmern, um angemessen auf Manipulationen zu reagieren.

Das interaktive Objekt fragt die attachTransform ab und kann jedes attachTransform gleich behandeln, unabhängig vom Typ des Interaktors.

Dieser Ansatz ist entscheidend für die Kompatibilität mit bestehenden XRI-Interaktoren sowie für die Zukunftssicherheit Ihrer Interaktionen für Eingabemodalitäten, die noch nicht entwickelt wurden. Wenn eine neue Eingabemethode eingeführt wird, müssen Sie die bestehenden Interagierbaren nicht ändern, wenn der neue Interaktor eine gültige und gut funktionierende attachTransform generiert.

Philosophisch gesehen ist das attachTransform also die Interaktionslogik. Ziehen Sie es für benutzerdefinierte Interaktionen immer vor, einen neuen Interaktor mit neuer attachTransform Logik zu schreiben, anstatt interaktive Objekte neu zu schreiben oder zu erweitern, um sie an Ihre neue Interaktion anzupassen. Auf diese Weise können alle vorhandenen interaktiven Elemente die Vorteile Ihrer neuen Interaktion nutzen, anstatt nur die, die Sie neu geschrieben oder erweitert haben.

XRControllers und Eingabebindung

Die meisten Interaktoren binden sich nicht direkt an Eingabeaktionen. Die meisten leiten sich von XRBaseControllerInteractor ab, was ein XRController oberhalb des Interaktors in der Hierarchie erfordert. Die XRController bindet an Eingabeaktionen und überträgt dann die entsprechenden Aktionen (auswählen usw.) auf alle angeschlossenen Interaktoren.

Dennoch benötigen einige Interaktoren möglicherweise spezielle Eingabebindungen oder zusätzliche Eingaben, die XRController nicht bereitstellt. In diesen Fällen haben Interaktoren die Möglichkeit, sich direkt an ihre eigenen eindeutigen Eingabeaktionen zu binden oder sogar andere Nicht-Eingabesystemquellen für die Interaktionslogik zu verwenden. Die XRI-Basisklassen ziehen es vor, auf die XRController's-Bindungen zu hören, aber diese Verhaltensweisen können überschrieben werden, um externe oder alternative Eingabequellen zu verwenden.

Schnittstellen

XRI definiert die grundlegenden IXRInteractor, IXRHoverInteractor, IXRSelectInteractor und IXRActivateInteractor. MRTK definiert zusätzliche Schnittstellen für Interaktoren. Einige stellen zusätzliche Informationen über MRTK-spezifische Wechselwirkungen bereit, andere sind lediglich zur Kategorisierung und Identifizierung. Diese Schnittstellen befinden sich alle innerhalb des Core-Pakets , während sich die Implementierungen in anderen Paketen befinden, einschließlich Eingabe.

Wichtig

Obwohl diese Schnittstellen hilfreich sind, wenn Sie nach einer bestimmten Art von Interaktion filtern müssen, empfehlen wir, Ihre Interaktionen nicht fest zu codieren, um speziell auf diese Schnittstellen zu hören. Bevorzugen Sie in jeder Situation immer das generische XRI isSelected und isHovered, anstatt einer interaktionsspezifischen Schnittstelle.

Sofern es nicht erforderlich ist, sollten Sie nicht auf die konkreten MRTK-Implementierungen dieser Schnittstellen in interaktiven Elementen verweisen, es sei denn, dies ist absolut erforderlich. In allen Fällen ist es besser, auf die Schnittstellen zu verweisen. Wenn Sie explizit auf die konkreten Typen verweisen, werden Ihre interaktiven Elemente darauf beschränkt, nur mit den aktuellen, vorhandenen Typen zu arbeiten. Indem Sie nur auf die Schnittstellen verweisen, stellen Sie die Kompatibilität mit zukünftigen Implementierungen sicher, die möglicherweise keine Unterklassen der vorhandenen Implementierungen bilden.

IVariableSelectInteractor

Interaktoren, die diese Schnittstelle implementieren, können variable (d.h. analoge) Auswahlmöglichkeiten an interaktive Objekte vergeben. Der Variablenauswahlbetrag kann mit der SelectProgress Eigenschaft abgefragt werden. Zu den MRTK-Interaktoren, die diese Schnittstelle implementieren, gehören MRTKRayInteractor und GazePinchInteractor. Basisinteraktoren (die Standard-XRI-Interaktoren und MRTKBaseInteractable) werden von der Variablenauswahl nicht beeinflusst. StatefulInteractable hingegen hört auf diesen Wert und berechnet sein Selectedness auf der Grundlage des max() aller beteiligten variablen und nicht-variablen Interaktoren.

IGazeInteractor

Interaktoren, die diese Schnittstelle implementieren, stellen den passiven Blick des Benutzers dar, getrennt von jeglicher Manipulation oder Absicht. Die MRTK-Implementierung ist FuzzyGazeInteractor, die von der XRI XRRayInteractor erbt und die Fuzzy-Cone-Casting-Logik hinzufügt. XRBaseInteractable wird gekennzeichnet IsGazeHovered , wenn ein IGazeInteractor angezeigt wird.

IGrabInteractor

Interaktoren, die diese Schnittstelle implementieren, stellen eine physische Nahfeld-Grabbing-Interaktion dar. Das attachTransform ist als Greifpunkt definiert. Die MRTK-Implementierung ist GrabInteractor, die eine Unterklasse von XRIs XRDirectInteractor ist.

IPokeInteractor

Interaktoren, die diese Schnittstelle implementieren, stellen eine Poking-Interaktion dar. Beachten Sie, dass dies nicht unbedingt bedeutet, dass es sich um einen Finger handelt! Beliebige Interaktoren können diese Schnittstelle implementieren und Poking-Interaktionen von Nicht-Finger-Quellen anbieten. In einem der wenigen Fälle, in denen die Überprüfung von Interaktorschnittstellen eine gute Idee ist, hören interaktive Elemente wie PressableButton auf IPokeInteractors, um insbesondere volumetrisches Drücken zu steuern. Jeder Interaktor, der IPokeInteractor implementiert, löst das Drücken von 3D-Tasten aus.

IPokeInteractor macht die PokeRadius Eigenschaft verfügbar, die die Merkmale des Pokingobjekts definiert. Der Poke gilt als zentriert auf dem attachTransform und erstreckt sich vom attachTransform aus nach außen durch den PokeRadius. Interaktive Elemente wie etwa PressableButton versetzen ihre 3D-Push-Distanz um diesen Radius, der von der physischen Fingerstärke des Benutzers im Fall von fingerbasierten Drücken gesteuert werden kann.

Die MRTK-Implementierung dieser Schnittstelle ist PokeInteractor. In unserem Vorlagenprojekt bieten wir auch ein weiteres Beispiel für einen IPokeInteractor, der nicht fingergesteuerte ist; PenInteractor bietet Anstupsen-Interaktionen, die auf der Spitze eines virtuellen 3D-Eingabestifts verankert sind.

IRayInteractor

Interaktoren, die diese Schnittstelle implementieren, stellen eine strahlenbasierte Zeigeinteraktion dar. attachTransform stellt die Trefferposition des Strahls auf der Oberfläche des zielbezogenen Objekts während einer Auswahl dar.

Die MRTK-Implementierung dieser Schnittstelle ist MRTKRayInteractor, die direkt vom XRI XRRayInteractor erbt.

Hinweis

XRI XRRayInteractor implementiert diese MRTK-Schnittstelle nicht.

ISpeechInteractor

Interaktoren, die diese Schnittstelle implementieren, stellen sprachgesteuerte Interaktionen dar. Die MRTK-Implementierung ist SpeechInteractor.

MRTK SpeechInteractor verwendet intern PhraseRecognitionSubsystem und abonniert interaktive Registrierungsereignisse vom XRI XRInteractionManager. Interaktive Objekte müssen sich jedoch keine Gedanken darüber machen, welches Subsystem die Sprachverarbeitung durchführt. ISpeechInteractoren erzeugen die gleichen XRI-Ereignisse (auswählen usw.) wie jeder andere Interaktor.

IGazePinchInteractor

Diese Schnittstelle ist einfach eine Spezialisierung der IVariableSelectInteractor Schnittstelle. Interaktoren, die diese Schnittstelle implementieren, sind implizit Interaktoren für die Variablenauswahl. IGazePinchInteractors stellen ausdrücklich eine indirekt gezielte Fernmanipulation dar. Ein separater blickbasierter Interaktor steuert das Ziel der Interaktion, und die Manipulation erfolgt durch eine Hand oder einen Controller. attachTransform verhält sich auf die gleiche Weise wie ein attachTransform eines IRayInteractors; es dockt an den Trefferpunkt am Ziel an, wenn eine Auswahl initiiert wird.

Wenn mehrere IGazePinchInteractors an einer einzelnen Interaktion teilnehmen, werden ihre attachTransforms durch ihre Verschiebung vom Medianpunkt zwischen allen beteiligten Pinch-Punkten versetzt. Daher können interaktive Elemente diese attachTransforms genauso interpretieren wie jede andere mehrhändige Interaktion, wie z.B. die attachTransforms von Greif- oder Strahleninteraktionen.

Die MRTK-Implementierung ist GazePinchInteractor.

IHandedInteractor

Einige Interaktoren können eine IHandedInteractor Schnittstelle implementieren, um explizit anzugeben, dass sie einem bestimmten Benutzer zugeordnet sind. Einige Interaktoren sind nicht mit der Hand verknüpft und implementieren dies daher nicht. Die offensichtlichsten Beispiele wären solche wie SpeechInteractor oder FuzzyGazeInteractor.

Die MRTK-Interaktoren, die diese Schnittstelle implementieren, sind das HandJointInteractor, ein generisches, abstraktes XRDirectInteractor, das durch ein beliebiges Handgelenk gesteuert wird, das GazePinchInteractor und das MRTKRayInteractor.

Interaktive Objekte verwenden derzeit diese Schnittstelle, um bestimmte Effekte zu auslösen, wenn ausgewählt ist, dass sie eine linke oder rechte Hand eindeutig machen müssen. Das bemerkenswerteste Beispiel hierfür ist der Pulseffekt in der UX-Komponentenbibliothek.