Hand menu — MRTK3
Met handmenu's kunnen gebruikers een met de hand gekoppelde gebruikersinterface openen voor veelgebruikte functies. Dit zijn meestal kleine knopgroepen die snelle acties bieden. Soms worden echter complexere indelingen voor het weergeven van informatie of instellingen aan de gebruiker aangeboden als een handmenu, vaak met de optie om het menu 'los te scheuren' van de hand en het in de wereld te verankeren.
Het menu Hand bevat de opties 'Flat Hand vereisen' en 'Gaze-activering gebruiken' om valse activering te voorkomen tijdens interactie met andere objecten. Het is raadzaam om deze opties te gebruiken om ongewenste activering te voorkomen.
Voorbeeldscène en prefabs
Als u het sjabloonproject gebruikt, HandMenuExamples.unity
ziet u verschillende algemene configuraties voor handmenu's, allemaal met behulp van het HandConstraintPalmUp
script.
HandMenuLarge
Deze prefab demonstreert het voorbeeld van een grote of complexe gebruikersinterface waarvoor uitgebreide interactietijd is vereist. Voor dit type gebruikersinterface is het raadzaam om het menu bij handdruppel te vergrendelen om de bruikbaarheid te verbeteren en armvermoeidheid te voorkomen. In dit voorbeeld wordt ook 'grab and pull' ondersteund om het menu wereldwijd te vergrendelen.
In dit voorbeeld wordt het menu zichtbaar en onzichtbaar door het menu te activeren op de gebeurtenis OnFirstHandDetected(). Met de gebeurtenis OnLastHandLost() wordt de knop Sluiten geactiveerd en wordt de plaatsingsanimatie geactiveerd. De animatie is een eenvoudige schaalschommeling. Omdat we de gebeurtenis MenuContent on OnLastHandLost() niet hebben verborgen, wordt het menu automatisch vergrendeld wanneer de hand niet zichtbaar is. De waarden in de sectie Palm Up zijn geoptimaliseerd om het menu wereld-vergrendeld te maken zonder te veel te worden gesleept op handdruppel.
Dit voorbeeld bevat de grijpbare balk in het onderste gedeelte van het menu en het automatische wereldvergrendelingsgedrag. De gebruiker kan het menu expliciet loskoppelen van de hand en het in de wereld plaatsen door dit te pakken. Om dit te bereiken, schakelen we in de gebeurtenis ManipulationStarted() in ObjectManipulator OplosserHandler.UpdateSolvers uit. Anders kan het menu niet worden losgekoppeld omdat HandConstraint oplosser het menu in de buurt van de handpositie probeert te plaatsen. We gebruiken ook HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine om de gebruiker in staat te stellen de hand op te steken om het menu opnieuw aan de hand te koppelen.
Ten slotte moet de knop Sluiten de OplosserHandler.UpdateSolvers opnieuw activeren om de functionaliteit van HandConstraint oplosser te herstellen.
Scripts
Het HandConstraint
gedrag biedt een oplosser die het bijgehouden object beperkt tot een regio die veilig is voor beperkte inhoud met de hand (zoals handgebruikersinterface, menu's, enzovoort) Veilige regio's worden beschouwd als gebieden die elkaar niet snijden met de hand. Een afgeleide klasse van HandConstraint
aangeroepen HandConstraintPalmUp
is ook opgenomen om een algemeen gedrag aan te tonen van het activeren van het oplosser-bijgehouden object wanneer de palm naar de gebruiker gericht is.
Zie de knopinfo die beschikbaar is voor elke HandConstraint
eigenschap voor aanvullende documentatie. Hieronder worden enkele eigenschappen nader gedefinieerd.
Veilige zone: de veilige zone geeft aan waar inhoud moet worden beperkt. Het wordt aanbevolen om inhoud aan de ulnar-zijde te plaatsen om overlapping met de hand en verbeterde interactiekwaliteit te voorkomen. Veilige zones worden berekend door de stand van de handen, geprojecteerd in een vlak dat orthogonaal is ten opzichte van de cameraweergave en raycasting tegen een begrenzingsvak rond de handen. Veilige zones zijn gedefinieerd voor gebruik met
XRNode
. Het wordt aanbevolen om te verkennen wat elke veilige zone vertegenwoordigt op verschillende typen controller.Hand volgen tot camera gericht Als deze actief is, zal de oplosser handrotatie volgen totdat het menu voldoende is uitgelijnd met de blik wanneer het naar de camera kijkt. Als u dit wilt laten werken, wijzigt u de
SolverRotationBehavior
in deHandConstraintSolver
, vanLookAtTrackedObject
naarLookAtMainCamera
omdat deGazeAlignment
hoek met de oplosser varieert.
Activeringsevenementen: Momenteel
HandConstraint
worden vier activeringsevenementen geactiveerd. Deze gebeurtenissen kunnen in veel verschillende combinaties worden gebruikt om uniekHandConstraint
gedrag te creëren.- OnHandActivate: wordt geactiveerd wanneer een hand voldoet aan de methode IsHandActive.
- OnHandDeactivate: wordt geactiveerd wanneer niet meer wordt voldaan aan de methode IsHandActive.
- OnFirstHandDetected: treedt op wanneer de status van handtracering verandert van geen handen in het zicht in de eerste hand in weergave.
- OnLastHandLost: treedt op wanneer de handtraceringsstatus verandert van ten minste één hand in weergave in geen handen in weergave.
Activerings-/deactiveringslogica voor Oplosser: Op dit moment is de aanbeveling voor het activeren en deactiveren van
HandConstraintPalmUp
logica dit te doen met behulp van deSolverHandler
UpdateSolver
-waarde in plaats van door het object uit te schakelen/in te schakelen. Dit is te zien in de voorbeeldscène via de editor-hooks die worden geactiveerd na de manipulatiehandler 'OnManipulationStarted/Ended' van het gekoppelde menu.-
De logica voor handbeperking stoppen: wanneer u probeert het handgeperkte object zo in te stellen dat deze stopt (en de activerings-/deactiveringslogica niet wordt uitgevoerd), stelt u UpdateSolver in op False in plaats van HandConstraintPalmUp uit te schakelen.
- Als u de logica voor opnieuw koppelen op basis van staren (of zelfs niet op basis van staren) wilt inschakelen, wordt dit gevolgd door het aanroepen van de
HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine()
functie. Hiermee wordt een coroutine geactiveerd die blijft controleren of aan de criteriaIsValidController
wordt voldaan en updatesolver wordt ingesteld op Waar zodra dit het geval is (of het object is uitgeschakeld).
- Als u de logica voor opnieuw koppelen op basis van staren (of zelfs niet op basis van staren) wilt inschakelen, wordt dit gevolgd door het aanroepen van de
- De handbeperkingslogica starten: wanneer u probeert het handbeperkingsobject in te stellen om uw hand opnieuw te volgen (op basis van of het voldoet aan de activeringscriteria), stelt u UpdateSolver van OplosserHandler in op true.
-
De logica voor handbeperking stoppen: wanneer u probeert het handgeperkte object zo in te stellen dat deze stopt (en de activerings-/deactiveringslogica niet wordt uitgevoerd), stelt u UpdateSolver in op False in plaats van HandConstraintPalmUp uit te schakelen.
-
Logica voor opnieuw koppelen: op dit moment kan het
HandConstraintPalmUp
doelobject automatisch opnieuw worden gekoppeld aan het bijgehouden punt, ongeacht of deSolverHandler
'sUpdateSolver
Waar is. Dit wordt gedaan door deHandConstraintPalmUp
functie 'sStartWorldLockReattachCheckCoroutine()
aan te roepen nadat deze is vergrendeld (wat in dit geval effectief is om de UpdateSolver van OplosserHandler in te stellen op False).