Controller, Zeiger und Fokus — MRTK2
Controller, Zeiger und Fokus sind übergeordnete Konzepte, die auf der Grundlage des Kerneingabesystems aufbauen. Zusammen stellen sie einen großen Teil des Mechanismus für die Interaktion mit Objekten in der Szene bereit.
Controller
Controller sind Darstellungen eines physischen Controllers (6 Freiheitsgrade, handgelenkte Hand usw.). Sie werden von Gerätemanagern erstellt und sind für die Kommunikation mit dem entsprechenden zugrunde liegenden System und die Übersetzung dieser Daten in MRTK-förmige Daten und Ereignisse verantwortlich.a
Beispielsweise ist auf der Windows Mixed Reality-Plattform ein Controller, der WindowsMixedRealityArticulatedHand
für die Interfacing mit den zugrunde liegenden Windows-Handverfolgungs-APIs verantwortlich ist, um Informationen über die Gelenke, Die Pose und andere Eigenschaften der Hand abzurufen. Es ist dafür verantwortlich, diese Daten in relevante MRTK-Ereignisse zu verwandeln (z. B. durch Aufrufen von RaisePoseInputChanged oder RaiseHandJointsUpdated) und durch Aktualisieren ihres eigenen internen Zustands, sodass Abfragen für TryGetJointPose
korrekte Daten zurückgeben.
Im Allgemeinen umfasst der Lebenszyklus eines Controllers Folgendes:
Ein Controller wird von einem Geräte-Manager erstellt, wenn eine neue Quelle erkannt wird (z. B. erkennt der Geräte-Manager eine Hand und beginnt mit der Nachverfolgung).
In der Update()-Schleife des Controllers wird das zugrunde liegende API-System aufgerufen.
In derselben Updateschleife löst sie Eingabeereignisänderungen aus, indem sie direkt in das Kerneingabesystem selbst aufruft (z. B. Das Auslösen von HandMeshUpdated oder HandJointsUpdated).
Zeiger und Fokus
Zeiger werden verwendet, um mit Spielobjekten zu interagieren. In diesem Abschnitt wird beschrieben, wie Zeiger erstellt werden, wie sie aktualisiert werden und wie sie die Objekte bestimmen, die im Fokus stehen. Außerdem werden die verschiedenen Arten von Zeigern und die Szenarien, in denen sie aktiv sind, behandelt.
Zeigerkategorien
Zeiger fallen in der Regel in eine der folgenden Kategorien:
Fernzeiger
Diese Arten von Zeigern werden verwendet, um mit Objekten zu interagieren, die weit vom Benutzer entfernt sind (weit entfernt wird einfach als "nicht nahe" definiert). Diese Art von Zeigern wandeln in der Regel Linien um, die weit in die Welt reichen können und es dem Benutzer ermöglichen, mit Objekten zu interagieren und sie zu bearbeiten, die sich nicht direkt neben ihnen befinden.
Nahzeiger
Diese Arten von Zeigern werden verwendet, um mit Objekten zu interagieren, die dem Benutzer nahe genug sind, um zu greifen, zu berühren und zu bearbeiten. Im Allgemeinen interagieren diese Arten von Zeigern mit Objekten, indem sie nach Objekten in der nähe gelegenen Umgebung suchen (entweder durch Raycasting in kleinen Entfernungen, durch sphärisches Casting nach Objekten in der Nähe oder durch Auflisten von Listen von Objekten, die als greifbar/touchierbar gelten).
Teleportzeiger
Diese Arten von Zeigern schließen sich an das Teleportationssystem an, um das Verschieben des Benutzers an die vom Zeiger bestimmte Position zu verarbeiten.
Zeigervermittlung
Da ein einzelner Controller über mehrere Zeiger verfügen kann (z. B. kann die Gelenkhand sowohl Nah- als auch Ferninteraktionszeiger aufweisen), gibt es eine Komponente, die für die Vermittlung des aktiven Zeigers verantwortlich ist.
Wenn sich die Hand des Benutzers beispielsweise einer drückenden Schaltfläche nähert, sollte die ShellHandRayPointer
nicht mehr angezeigt werden, und die PokePointer
sollte eingeschaltet werden.
Dies wird von behandelt, das für die DefaultPointerMediator
Bestimmung der aktiven Zeiger verantwortlich ist, basierend auf dem Zustand aller Zeiger. Eine der wichtigsten Aufgaben ist die Deaktivierung von fernen Zeigern, wenn sich ein Nahezeiger in der Nähe eines Objekts befindet (siehe DefaultPointerMediator
).
Es ist möglich, eine alternative Implementierung des Zeigermediators bereitzustellen, indem Sie die PointerMediator
Eigenschaft im Zeigerprofil ändern.
Deaktivieren von Zeigern
Da der Zeigermediator jeden Frame ausführt, steuert er schließlich den aktiven/inaktiven Zustand aller Zeiger. Wenn Sie also die IsInteractionEnabled-Eigenschaft eines Zeigers im Code festlegen, wird sie von jedem Frame vom Zeigermediator überschrieben. Stattdessen können Sie den PointerBehavior
angeben, um zu steuern, ob Zeiger selbst ein- oder ausgeschaltet werden sollen. Beachten Sie, dass dies nur funktioniert, wenn Sie die Standardeinstellung FocusProvider
und DefaultPointerMediator
in MRTK verwenden.
Beispiel: Deaktivieren von Handstrahlen in MRTK
Der folgende Code deaktiviert die Handstrahlen in MRTK:
// Turn off all hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);
// Turn off hand rays for the right hand only
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Right);
Der folgende Code gibt Handstrahlen auf ihr Standardverhalten in MRTK zurück:
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.Default);
Der folgende Code erzwingt das Einschalten von Handstrahlen, unabhängig davon, ob sie sich in der Nähe eines Greifbares befindet:
// Turn off all hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOn);
Weitere Beispiele finden Sie unter PointerUtils
und TurnPointersOnOff
.
FocusProvider
Das FocusProvider
ist das Arbeitspferd, das für das Durchlaufen der Liste aller Zeiger und das Ermitteln des fokussierten Objekts für jeden Zeiger verantwortlich ist.
Bei jedem Update()
Aufruf erfolgt Folgendes:
Aktualisieren Sie alle Zeiger, indem Sie raycasting und Treffererkennung durchführen, die vom Zeiger selbst konfiguriert ist (beispielsweise könnte der Kugelzeiger den SphereOverlap-RaycastMode angeben, sodass FocusProvider eine kugelbasierte Kollision ausführt).
Aktualisieren Sie das fokussierte Objekt pro Zeiger (d. h. wenn ein Objekt den Fokus gewinnt, würde es auch Ereignisse für dieses Objekt auslösen, wenn ein Objekt den Fokus verliert, würde es den Fokus verlieren usw.).
Zeigerkonfiguration und Lebenszyklus
Zeiger können im Abschnitt Zeiger des Eingabesystemprofils konfiguriert werden.
Die Lebensdauer eines Zeigers ist im Allgemeinen wie folgt:
Ein Geräte-Manager erkennt das Vorhandensein eines Controllers. Dieser Geräte-Manager erstellt dann den Satz von Zeigern, die dem Controller zugeordnet sind, über einen Aufruf von
RequestPointers
.Der FocusProvider in seiner Update()-Schleife durchläuft alle gültigen Zeiger und führt die zugehörige Raycast- oder Treffererkennungslogik durch. Dies wird verwendet, um das Objekt zu bestimmen, das von jedem bestimmten Zeiger fokussiert wird.
- Da es möglich ist, dass mehrere Eingabequellen gleichzeitig aktiv sind (z. B. zwei aktive Hände), ist es auch möglich, mehrere Objekte gleichzeitig zu verwenden, die den Fokus haben.
Wenn der Geräte-Manager feststellt, dass eine Controllerquelle verloren gegangen ist, reißt er die Zeiger ab, die dem verlorenen Controller zugeordnet sind.