Handmenü – MRTK3

Hand Menu

Mit Handmenüs können Benutzer die benutzerdefinierte Benutzeroberfläche für häufig verwendete Funktionen aufrufen. Dies sind in der Regel kleine Schaltflächengruppen , die schnelle Aktionen bieten. Manchmal werden jedoch komplexere Layouts zum Anzeigen von Informationen oder Einstellungen für den Benutzer als Handmenü bereitgestellt, oft mit der Option zum "Abreißen" des Menüs aus der Hand und verankern sie in der Welt.

Das Menü "Hand" bietet Optionen "Flache Hand erfordern" und "Verwenden der Blickaktivierung", um die Falschaktivierung während der Interaktion mit anderen Objekten zu verhindern. Es wird empfohlen, diese Optionen zu verwenden, um unerwünschte Aktivierung zu verhindern.

Beispielszene und Prefabs

Hinweis

Die Voreinstellungen für das Handmenü werden derzeit mithilfe der Nicht-Canvas-Steuerelemente erstellt. Sie werden bald mit den Canvas-Komponenten und dem Autolayoutsystem wie in der Schaltflächengruppe-Dokumentation beschrieben neu erstellt.

Wenn Sie das Vorlagenprojekt verwenden, werden mehrere allgemeine Konfigurationen für Handmenüs veranschaulicht, HandMenuExamples.unity die alle das HandConstraintPalmUp Skript verwenden.

Hand Menu Example Scene

HandMenu1x4 und HandMenu2x4

Das Menü wird in diesen Prefabs sichtbar und unsichtbar, indem das MenuContent-Objekt auf OnFirstHandLost() und OnLastHandLost() -Ereignissen aktiviert und deaktiviert wird. Dieses Verhalten wird für das Menü mit einer kleinen Benutzeroberfläche empfohlen, die eine kurze Interaktionszeit erfordert.

Hand Menu Example 2x4

HandMenuLarge

In diesem Prefab wird das Beispiel einer großen oder komplexen Benutzeroberfläche veranschaulicht, die eine erweiterte Interaktionszeit erfordert. Für diese Art von Benutzeroberfläche empfiehlt es sich, das Menü auf der Hand zu sperren, um die Benutzerfreundlichkeit zu verbessern und Armmüdigkeit zu vermeiden. In diesem Beispiel wird auch "Grab and Pull" unterstützt, um das Menü zu sperren.

In diesem Beispiel wird das Menü sichtbar und unsichtbar, indem das MenuContent-Objekt auf OnFirstHandDetected() -Ereignis aktiviert wird. Mit dem OnLastHandLost() -Ereignis wird die Schaltfläche "Schließen" aktiviert, und die Platzierungsanimation wird ausgelöst. Die Animation ist eine einfache Skalierungsschwankung. Da wir das MenuContent-Ereignis auf OnLastHandLost() nicht ausgeblendet haben, wird das Menü automatisch weltgesperrt, wenn die Hand nicht sichtbar ist. Die Werte im Palm Up-Abschnitt wurden optimiert, um das Menü weltgesperrt zu machen, ohne zu viel auf der Hand zu ziehen.

Hand Menu Example Large 1

Palm Up configuration

In diesem Beispiel wird die Ziehleiste im unteren Bereich des Menüs und das automatische Weltsperrverhalten bereitgestellt. Der Benutzer kann das Menü explizit von der Hand trennen und es in der Welt platzieren, indem er dies ergreift. Um dies zu erreichen, deaktivieren wir solverHandler.UpdateSolvers auf dem ManipulationStarted()-Ereignis in ObjectManipulator. Andernfalls kann das Menü nicht getrennt werden, da HandConstraint-Solver versucht, das Menü in der Nähe der Handposition zu positionieren. Wir verwenden auch HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine , um dem Benutzer die Hand zu ermöglichen, das Menü erneut an die Hand zu setzen.

Hand Menu Example Large 2

Schließlich muss die Schaltfläche "Schließen" die SolverHandler.UpdateSolvers erneut aktivieren, um die Funktionalität des HandConstraint-Solvers wiederherzustellen.

Hand Menu Example Large 3

Skripts

Das HandConstraint-Verhalten bietet einen Solver, der das nachverfolgte Objekt auf einen Bereich beschränkt, der für auf die Hände eingeschränkte Inhalte (z. B. Handbenutzeroberfläche, Menüs usw.) sicher ist. Sichere Regionen gelten als Bereiche, die sich nicht mit der Hand überschneiden. Eine abgeleitete Klasse von HandConstraint namens HandConstraintPalmUp ist ebenfalls enthalten, um ein allgemeines Verhalten der Aktivierung des vom Solver verfolgten Objekts zu veranschaulichen, wenn die Handfläche dem Benutzer zugewandt ist.

Weitere Dokumentationen finden Sie in den QuickInfos für jede HandConstraint Eigenschaft. Einige Eigenschaften werden unten ausführlicher definiert.

  • Tresor Zone: Die sichere Zone gibt an, wo der Inhalt eingeschränkt werden soll. Es wird empfohlen, Inhalte auf der Ulnar-Seite zu platzieren, um Überlappen mit der Hand zu vermeiden und die Interaktionsqualität zu verbessern. Tresor Zonen werden durch die Ausrichtung der Hände in ein Flugzeug orthogonal auf die Ansicht der Kamera und der Raycasting gegen ein gebundenes Feld um die Hände berechnet. Tresor Zonen werden für die Arbeit mit XRNode. Die Untersuchung, was jede sichere Zone für verschiedene Controllertypen darstellt, wird empfohlen.

  • Folgen Sie der Hand, bis Kamera Mit diesem aktiven Löser wird die Handdrehung folgen, bis das Menü ausreichend mit dem Blick ausgerichtet ist, wenn er der Kamera gegenübersteht. Um diese Arbeit zu machen, ändern Sie das SolverRotationBehavior In HandConstraintSolverder GazeAlignment , von LookAtTrackedObject bis LookAtMainCamera zu dem Winkel mit dem Solver variiert.

Hand Menu Example Safe Zone

  • Aktivierungsereignisse: Derzeit werden vier HandConstraint Aktivierungsereignisse ausgelöst. Diese Ereignisse können in vielen verschiedenen Kombinationen verwendet werden, um eindeutige HandConstraint Verhaltensweisen zu erstellen.

    • OnHandActivate: Trigger, wenn eine Hand die IsHandActive-Methode erfüllt.
    • OnHandDeactivate: Trigger, wenn die IsHandActive-Methode nicht mehr erfüllt ist.
    • OnFirstHandDetected: Tritt auf, wenn sich der Handverfolgungszustand von keiner Hand in der Ansicht auf die erste Hand ändert.
    • OnLastHandLost: Tritt auf, wenn sich der Handverfolgungszustand von mindestens einer Hand in Der Ansicht auf keine Hände ändert.
  • Solver-Aktivierungs-/Deaktivierungslogik: Derzeit besteht die Empfehlung zum Aktivieren und Deaktivieren HandConstraintPalmUp der Logik darin, dies mithilfe des Werts zu tun, anstatt das SolverHandlerUpdateSolver Objekt zu deaktivieren/zu aktivieren. Dies kann in der Beispielszene durch die Editor-basierten Hooks angezeigt werden, die nach den "OnManipulationStarted/End"-Ereignissen des angefügten Menüs ausgelöst wurden.

    • Beenden der Handeinschränkungslogik: Wenn Sie versuchen, das handbeschränkte Objekt zu beenden (und nicht die Aktivierungs-/Deaktivierungslogik auszuführen), legen Sie UpdateSolver auf False fest, anstatt HandConstraintPalmUp zu deaktivieren.
      • Wenn Sie die blickbasierte (oder sogar nicht blickbasierte) Reattach-Logik aktivieren möchten, wird dies dann durch Aufrufen der HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine() Funktion gefolgt. Dadurch wird ein Coroutine ausgelöst, das weiterhin überprüft, ob die "IsValidController"-Kriterien erfüllt sind und UpdateSolver auf "True" festlegen, sobald es sich um "True" handelt (oder das Objekt deaktiviert ist).
    • Starten sie die Handeinschränkungslogik: Wenn Sie versuchen, das handbeschränkte Objekt festzulegen, um erneut nach ihrer Hand zu beginnen (basierend auf der Erfüllung der Aktivierungskriterien), legen Sie den UpdateSolver des SolverHandlers auf true fest.
  • Reattach Logic: Derzeit kann das HandConstraintPalmUp Zielobjekt automatisch an den nachverfolgten Punkt zurückgelöst werden, unabhängig davon, ob dies SolverHandlerUpdateSolver "True" ist. Dadurch wird die HandConstraintPalmUpStartWorldLockReattachCheckCoroutine() Funktion aufgerufen, nachdem sie weltgesperrt wurde (was in diesem Fall effektiv das UpdateSolver des SolverHandlers auf "False" festgelegt hat).