Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Solver sind Komponenten, die die Berechnung der Position und Ausrichtung eines Objekts gemäß einem vordefinierten Algorithmus erleichtern. Beispiel: Platzieren eines Objekts auf der Oberfläche, mit der sich der Blickstrahl des Benutzers überschneidet.
Das Solver-System definiert deterministisch eine Reihenfolge von Vorgängen für diese Transformationsberechnungen, da es keine zuverlässige Möglichkeit gibt, Unity die Updatereihenfolge für Komponenten anzugeben.
Solver bieten eine Reihe von Verhaltensweisen zum Anfügen von Objekten an andere Objekte oder Systeme. Ein weiteres Beispiel wäre ein Tag-along-Objekt, das basierend auf der Kamera vor dem Benutzer bewegt wird. Ein Solver kann auch an einen Controller und ein -Objekt angefügt werden, um das Objekt entlang des Controllers als Tag festzulegen. Alle Solver können sicher gestapelt werden, z. B. ein Tag-Along-Verhalten plus Oberflächenmagnetismus plus Impuls.
Anleitung
Das Solver-System besteht aus drei Kategorien von Skripts:
-
Solver: Die abstrakte Basisklasse, von der alle Solver abgeleitet werden. Es bietet Zustandsnachverfolgung, Glättungsparameter und Implementierung, automatische Solver-Systemintegration und Updatereihenfolge. -
SolverHandler: Legt die Nachverfolgung des Referenzobjekts für fest (Beispiel: Hauptkameratransformation, Handstrahl usw.), übernimmt das Sammeln von Solverkomponenten und führt die Aktualisierung in der richtigen Reihenfolge aus.
Die dritte Kategorie ist der Solver selbst. Die folgenden Solver stellen die Bausteine für das grundlegende Verhalten bereit:
-
Orbital: Sperrt an einer angegebenen Position und einem Offset des Objekts, auf das verwiesen wird. -
ConstantViewSize: Skaliert, um eine konstante Größe relativ zur Ansicht des Objekts beizubehalten, auf das verwiesen wird. -
RadialView: Behält das Objekt in einem Ansichtskegel bei, der vom Objekt, auf das verwiesen wird, umgewandelt wird. -
Follow: Hält das -Objekt innerhalb eines Satzes benutzerdefinierter Grenzen des Objekts, auf das verwiesen wird. -
InBetween: Behält ein Objekt zwischen zwei nachverfolgten Objekten bei. -
SurfaceMagnetism: Wirft Strahlen auf Oberflächen in der Welt und richtet das Objekt an dieser Oberfläche aus. -
DirectionalIndicator: Bestimmt die Position und Ausrichtung eines Objekts als Richtungsindikator. Vom Bezugspunkt des SolverHandler Tracked Target wird dieser Indikator auf das angegebene DirectionalTarget ausgerichtet. -
Momentum: Wendet Beschleunigung/Geschwindigkeit/Reibung an, um Dynamik und Federung für ein Objekt zu simulieren, das von anderen Solvern/Komponenten bewegt wird. -
HandConstraint: Einschränkungsobjekt zum Folgen von Händen in einem Bereich, der das GameObject nicht mit den Händen überschneidet. Nützlich für von Hand eingeschränkte interaktive Inhalte wie Menüs usw. Dieser Solver ist für die Arbeit mitXRNodevorgesehen. -
HandConstraintPalmUp: Wird von HandConstraint abgeleitet, enthält jedoch Logik, um zu testen, ob die Handfläche vor der Aktivierung dem Benutzer zugewandt ist. Dieser Solver funktioniert nur mitXRNodeControllern und verhält sich genau wie seine Basisklasse mit anderen Controllertypen. -
Overlap: Überlappt das nachverfolgte Objekt.
Um das Solver-System zu verwenden, fügen Sie einem GameObject eine der oben aufgeführten Komponenten hinzu. Da alle Solver einen SolverHandlererfordern, wird eine von Unity automatisch erstellt.
Hinweis
Beispiele für die Verwendung des Solvers-Systems finden Sie in der Datei SolverExamples.scene .
Ändern der Nachverfolgungsreferenz
Die Tracked Target Type - Eigenschaft der SolverHandler Komponente definiert den Bezugspunkt, den alle Solver zum Berechnen ihrer Algorithmen verwenden. Beispielsweise führt ein Werttyp von Head mit einer einfachen SurfaceMagnetism Komponente zu einem Strahlwurf vom Kopf und in die Richtung des Anvisierens des Benutzers, um zu lösen, welche Oberfläche getroffen wird. Mögliche Werte für die TrackedTargetType Eigenschaft sind:
- *Kopf: Bezugspunkt ist die Transformation der Hauptkamera
-
ControllerRay: Bezugspunkt ist die
LinePointerTransformation auf einem Controller (d. a. Zeigerursprung auf einem Bewegungscontroller oder Handcontroller), der in Richtung des Linienstrahls zeigt.- Verwenden Sie die
TrackedHandedness-Eigenschaft, um die Händigkeitseinstellung auszuwählen (d. b. Links, Rechts, Beide).
- Verwenden Sie die
-
HandJoint: Bezugspunkt ist die Transformation eines bestimmten Handgelenks.
- Verwenden Sie die
TrackedHandedness-Eigenschaft, um die Händigkeitseinstellung auszuwählen (d. b. Links, Rechts, Beide). - Verwenden Sie die
TrackedHandJoint-Eigenschaft, um die zu verwendende gemeinsame Transformation zu bestimmen.
- Verwenden Sie die
-
CustomOverride: Bezugspunkt aus dem zugewiesenen
TransformOverride
Hinweis
Sowohl für ControllerRay - als auch für HandJoint-Typen versucht der Solver-Handler, zuerst die linke Controller-/Handtransformation und dann die rechte bereitzustellen, wenn erstere nicht verfügbar ist oder die TrackedHandedness -Eigenschaft nichts anderes angibt.
Wichtig
Die meisten Solver verwenden den Vorwärtsvektor des verfolgten Transformationsziels, das SolverHandlervon bereitgestellt wird. Bei Verwendung eines verfolgten Handgelenk-Zieltyps kann der Vorwärtsvektor des Handflächengelenks durch die Finger und nicht durch die Handfläche zeigen. Dies hängt von der Plattform ab, die die Handgelenkdaten liefert. Für eingabesimulation und Windows Mixed Reality zeigt der Vektor nach oben durch die Handfläche (mit anderen Worten, grüner Vektor ist up, blauer Vektor ist vorwärts).
Um dies zu umgehen, aktualisieren Sie die Eigenschaft Zusätzliche Drehung für den SolverHandler auf <90, 0, 0>. Dadurch wird sichergestellt, dass der den Solvern bereitgestellte Vorwärtsvektor durch die Handfläche und von der Hand nach außen zeigt.
Alternativ können Sie den Zieltyp Controller Ray tracked verwenden, um ein ähnliches Verhalten beim Zeigen mit den Händen zu erhalten.
Verketten von Solvern
Es ist möglich, demselben GameObject mehrere Solver Komponenten hinzuzufügen und so deren Algorithmen zu verketten. Die SolverHandler Komponenten übernehmen die Aktualisierung aller Solver auf demselben GameObject. Standardmäßig rufen die -Elemente GetComponents<Solver>() auf der SolverHandler Startseite auf, wodurch die Solver in der Reihenfolge zurückgegeben werden, in der sie im Inspektor angezeigt werden.
Darüber hinaus weist das Festlegen der Eigenschaft Updated Linked Transform auf true an, dass Solver die berechnete Position und Ausrichtung gespeichert und auf eine zwischengeschaltete Variable skaliert wird, GoalPositionauf die alle Solver zugreifen können (d. a. ). Bei "false" wird die Solver Transformation des GameObject direkt aktualisiert. Indem die Transformationseigenschaften an einem zwischengeschalteten Speicherort gespeichert werden, können andere Solver ihre Berechnungen ab der Zwischenvariablen ausführen. Dies liegt daran, dass Unity nicht zulässt, dass Updates für gameObject.transform innerhalb desselben Frames gestapelt werden.
Hinweis
Entwickler können die Ausführungsreihenfolge von Solvers ändern, indem sie die SolverHandler.Solvers -Eigenschaft direkt festlegen.
Erstellen eines neuen Solvers
Alle Solver müssen von der abstrakten Basisklasse erben. Solver Die primären Anforderungen einer Solver-Erweiterung umfassen das Überschreiben der SolverUpdate -Methode. In dieser Methode sollten Entwickler die geerbten GoalPositionEigenschaften , GoalRotationund GoalScale auf die gewünschten Werte aktualisieren. Darüber hinaus ist es hilfreich, als Bezugsrahmen zu nutzen SolverHandler.TransformTarget , der vom Verbraucher gewünscht wird.
Der unten angegebene Code enthält ein Beispiel für eine neue Solver-Komponente namens InFront , die das angefügte Objekt 2 m vor dem SolverHandler.TransformTargetplatziert. Der Consumer legt als HeadfestSolverHandler.TrackedTargetType, dann wird die SolverHandler.TransformTarget Kameratransformation, und daher platziert dieser Solver das angeschlossene GameObject 2 m vor dem Anvisieren jedes Frames des Benutzers.
/// <summary>
/// InFront solver positions an object 2m in front of the tracked transform target
/// </summary>
public class InFront : Solver
{
...
public override void SolverUpdate()
{
if (SolverHandler != null && SolverHandler.TransformTarget != null)
{
var target = SolverHandler.TransformTarget;
GoalPosition = target.position + target.forward * 2.0f;
}
}
}
Solver-Implementierungsleitfäden
Allgemeine Solvereigenschaften
Jede Solver-Komponente verfügt über einen Kernsatz identischer Eigenschaften, die das Solver-Kernverhalten steuern.
Wenn glätten aktiviert ist, aktualisiert Solver die Transformation des GameObject im Laufe der Zeit schrittweise auf die berechneten Werte. Die LerpTime-Eigenschaft jeder Transformationskomponente bestimmt die Geschwindigkeit dieser Änderung. Beispielsweise führt ein höherer MoveLerpTime-Wert zu langsameren Inkrementen bei der Bewegung zwischen Frames.
Wenn MaintainScale aktiviert ist, verwendet solver die lokale Standardskalierung von GameObject.
Orbital
Die Orbital -Klasse ist eine Tag-along-Komponente, die sich wie Planeten in einem Sonnensystem verhält. Dieser Solver stellt sicher, dass das angefügte GameObject die nachverfolgte Transformation umrundet. Wenn also der Nachverfolgte Zieltyp des SolverHandler auf Headfestgelegt ist, wird das GameObject um den Kopf des Benutzers herum kreisen, wobei ein fester Offset angewendet wird.
Entwickler können diesen festen Offset ändern, um Menüs oder andere Szenenkomponenten auf Augen- oder Taillenebene usw. um einen Benutzer herum zu halten. Dies erfolgt durch Ändern der Eigenschaften Lokaler Offset und Weltoffset . Die Orientation Type-Eigenschaft bestimmt die Drehung, die auf das Objekt angewendet wird, wenn es seine ursprüngliche Drehung beibehalten oder immer der Kamera oder dem Gesicht zugewandt werden soll, unabhängig davon, welche Transformation seine Position bestimmt.
RadialView
Ist RadialView eine weitere Tag-along-Komponente, die einen bestimmten Teil eines GameObject innerhalb des Frustums der Ansicht des Benutzers behält.
Die Eigenschaften Min & Max View Degrees bestimmen, wie viel von einem Teil des GameObject immer sichtbar sein muss.
Die Eigenschaften Min & Max Distance bestimmen, wie weit das GameObject vom Benutzer entfernt bleiben soll. Wenn Sie z. B. mit einer Mindestdistanz von 1 m auf das GameObject zugehen, wird das GameObject entfernt, um sicherzustellen, dass es dem Benutzer nie näher als 1 m ist.
Im Allgemeinen wird verwendet, wenn der RadialViewTracked Target Type auf Head festgelegt ist, sodass die Komponente dem Anvisieren des Benutzers folgt. Diese Komponente kann jedoch so funktionieren, dass sie in der "Ansicht" eines beliebigen nachverfolgten Zieltyps beibehalten wird.
Folgen
Die Follow -Klasse positioniert ein Element relativ zur lokalen Vorwärtsachse vor dem nachverfolgten Ziel. Das Element kann lose eingeschränkt werden (auch als "tag-along" bezeichnet), sodass es erst folgt, wenn das nachverfolgte Ziel über benutzerdefinierte Grenzen hinaus bewegt wird.
Es funktioniert ähnlich wie der RadialView-Solver mit zusätzlichen Steuerelementen zum Verwalten der maximalen horizontalen & Grad der vertikalen Ansicht und Mechanismen zum Ändern der Ausrichtung des Objekts.
Dazwischen
Die InBetween -Klasse behält das angefügte GameObject zwischen zwei Transformationen bei. Die beiden Transformationsendpunkte werden vom gameObject-eigenen SolverHandlerNachverfolgten Zieltyp und der Second Tracked Target Type-Eigenschaft der InBetween Komponente definiert. Im Allgemeinen werden beide Typen auf CustomOverride festgelegt, und die resultierenden SolverHandler.TransformOverride Werte und InBetween.SecondTransformOverride werden auf die beiden nachverfolgten Endpunkte festgelegt.
Die InBetween Komponente erstellt zur Laufzeit eine weitere SolverHandler Komponente basierend auf den Eigenschaften Second Tracked Target Type und Second Transform Override .
Entlang der Linie zwischen zwei Transformationen definiert, wo das Objekt platziert wird, PartwayOffset wobei 0,5 als halber Weg, 1,0 bei der ersten Transformation und 0,0 bei der zweiten Transformation platziert wird.
SurfaceMagnetism
Die SurfaceMagnetism funktioniert, indem ein Raycast für eine festgelegte LayerMask von Oberflächen ausgeführt und das GameObject an diesem Kontaktpunkt platziert wird.
Der Surface Normal Offset platziert das GameObject in einem festgelegten Abstand in Metern von der Oberfläche in Richtung des Normalen am Trefferpunkt auf der Oberfläche.
Umgekehrt platziert der Surface Ray Offset das GameObject in einem festgelegten Abstand in Metern von der Oberfläche entfernt, aber in der entgegengesetzten Richtung des durchgeführten Raycasts. Wenn der Raycast also das Anvisieren des Benutzers ist, bewegt sich das GameObject näher entlang der Linie vom Trefferpunkt auf der Oberfläche zur Kamera.
Der Ausrichtungsmodus bestimmt die Art der Drehung, die in Bezug auf die Normalität auf der Oberfläche angewendet werden soll.
- Keine : Keine Drehung angewendet
- TrackedTarget : Das Objekt stellt sich der verfolgten Transformation, die den Raycast antreibt.
- SurfaceNormal : Das Objekt wird am Trefferpunkt auf der Oberfläche normal ausgerichtet
- Blended : Das Objekt wird basierend auf der Normalität am Trefferpunkt auf der Oberfläche UND basierend auf der Ausrichtung der verfolgten Transformation ausgerichtet.
Um zu erzwingen, dass das zugeordnete GameObject in einem anderen Modus als Keine vertikal bleibt, aktivieren Sie Ausrichtung vertikal beibehalten.
Hinweis
Verwenden Sie die Orientation Blend-Eigenschaft , um das Gleichgewicht zwischen Drehfaktoren zu steuern, wenn der Ausrichtungsmodus auf Blended festgelegt ist. Bei einem Wert von 0,0 wird die Ausrichtung vollständig vom TrackedTarget-Modus gesteuert, und bei einem Wert von 1,0 wird die Ausrichtung vollständig von SurfaceNormal gesteuert.
Overlap
ist Overlap ein einfacher Solver, der die Transformation des Objekts an der gleichen Position und Drehung wie das SolverHandler's Transformationsziel hält.
Bestimmen, welche Oberflächen getroffen werden können
Beim Hinzufügen einer SurfaceMagnetism Komponente zu einem GameObject ist es wichtig, die Ebene des GameObjects und seine untergeordneten Elemente zu berücksichtigen, falls diese über Collider verfügen. Die Komponente arbeitet durch verschiedene Raycasts, um zu bestimmen, gegen welche Oberfläche sie sich "magnetisieren". Angenommen, der Solver GameObject verfügt über einen Collider auf einer der Ebenen, die in der MagneticSurfaces -Eigenschaft von SurfaceMagnetismaufgeführt sind. In diesem Fall trifft sich der Raycast wahrscheinlich selbst, was dazu führt, dass das GameObject an seinen eigenen Colliderpunkt angefügt wird. Dieses ungewöhnliche Verhalten kann vermieden werden, indem sie das Haupt-GameObject und alle untergeordneten Elemente auf die Schicht Strahlumwandlung ignorieren festlegen oder das MagneticSurfaces LayerMask-Array entsprechend ändern.
Umgekehrt kollidiert ein SurfaceMagnetism GameObject nicht mit Oberflächen auf einer Ebene, die nicht in der MagneticSurfaces -Eigenschaft aufgeführt ist. Es wird empfohlen, alle gewünschten Oberflächen auf einer dedizierten Ebene (d. h . Surfaces) zu platzieren und die MagneticSurfaces -Eigenschaft nur auf diese Ebene festzulegen. Die Verwendung von Standard oder alles kann dazu führen, dass Benutzeroberflächenkomponenten oder Cursor zum Solver beitragen.
Schließlich werden Oberflächen, die weiter als die MaxRaycastDistance -Eigenschaftseinstellung sind, von den SurfaceMagnetism Raycasts ignoriert.
DirectionalIndicator
Die DirectionalIndicator -Klasse ist eine Tag-along-Komponente, die sich an der Richtung des gewünschten Punkts im Raum orientiert. Es wird am häufigsten verwendet, wenn der Nachverfolgte Zieltyp von SolverHandler auf Headfestgelegt ist. Auf diese Weise weist eine UX-Komponente mit dem DirectionalIndicator Solver einen Benutzer an, den gewünschten Punkt im Raum zu betrachten. Dieser Punkt wird durch die Eigenschaft Directional Target bestimmt.
Wenn das direktionale Ziel vom Benutzer angezeigt werden kann oder welcher Bezugsrahmen im SolverHandlerfestgelegt ist, deaktiviert dieser Solver alle Renderer Komponenten darunter. Wenn nicht angezeigt werden kann, wird alles auf dem Indikator aktiviert.
Die Größe des Indikators wird kleiner, je näher der Benutzer an der Erfassung des richtungsgerichteten Ziels in seiner FOV ist.
Minimale Indikatorskala – Die Mindestskala für das Indikatorobjekt
Maximale Indikatorskala : Die maximale Skalierung für das Indikatorobjekt
Sichtbarkeitsskalierungsfaktor : Multiplikator zum Erhöhen oder Verringern der FOV, der bestimmt, ob der direktionale Zielpunkt sichtbar ist oder nicht
Ansichtsoffset : Aus Sicht des Bezugsrahmens (d. h. möglicherweise kamera) und in Der Indikatorrichtung definiert diese Eigenschaft, wie weit sich das Objekt von der Mitte des Viewports entfernt befindet.
Beispielszene für einen direktionalen Indikator (Assets/MRTK/Examples/Demos/Solvers/Scenes/DirectionalIndicatorSolverExample.unity)
Handmenü mit HandConstraint und HandConstraintPalmUp
Das HandConstraint Verhalten stellt einen Solver bereit, der das nachverfolgte Objekt auf einen Bereich einschränkt, der für handbeschränkte Inhalte (z. B. Handbenutzeroberfläche, Menüs usw.) sicher ist. Sichere Regionen werden als Bereiche betrachtet, die sich nicht mit der Hand überschneiden. Eine abgeleitete Klasse von HandConstraint aufgerufen HandConstraintPalmUp ist ebenfalls enthalten, um ein allgemeines Verhalten der Aktivierung des solvertracked-Objekts zu veranschaulichen, wenn die Handfläche dem Benutzer zugewandt ist.
Beispiele für die Verwendung des Handeinschränkungs-Solvers zum Erstellen von Handmenüs finden Sie in der Handmenüdokumentation.