Handmeny – MRTK2

UX-exempel på handmeny

Med handmenyer kan användarna snabbt ta fram handanslutet användargränssnitt för funktioner som används ofta. För att förhindra falsk aktivering när du interagerar med andra objekt, innehåller handmenyn alternativ som "Kräv platt hand" och "Använd blickaktivering". Vi rekommenderar att du använder de här alternativen för att förhindra oönskad aktivering.

Exempel på handmeny

HandMenuExamples.unity-scenen finns under MRTK/Examples/Demos/HandTracking/Scenes mappen . När den körs aktiveras endast den valda menytypen i scenen.
HandMenu_ExampleScene

De här handmenyprefaberna finns under MRTK/Examples/Common/Prefabs mappen .

HandMenu_Small_HideOnHandDrop och HandMenu_Medium_HideOnHandDrop

De här två exemplen aktiverar och inaktiverar bara objektet MenuContent för att visa och dölja menyn på OnFirstHandDetected() och OnLastHandLost() händelsen.
HandMenu_ExampleScene 1
HandMenu_ExampleScene 2

HandMenu_Large_WorldLock_On_GrabAndPull

För mer komplexa menyer som kräver längre interaktionstid rekommenderar vi att du låser menyn världen över. I det här exemplet kan användaren hämta och hämta för att världslåsa menyn, förutom att aktivera och inaktivera MenuContent på OnFirstHandDetected() och OnLastHandLost() händelser.
HandMenu_ExampleScene 3

Backplate's ManipulationHandler gör det grabbbart och flyttbart. Vid manipulationsstartad händelse inaktiveras SolverHandler.UpdateSolvers för att världslåsa menyn. Dessutom visas knappen Stäng så att användaren kan stänga menyn när uppgiften är klar. Vid manipulation avslutades händelse, det kallar HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine för att låta användaren ta menyn tillbaka till hands genom att höja och titta på handflatan.
HandMenu_ExampleScene 4

Stäng knappen reactivates SolverHandler.UpdateSolvers och döljer MenuContent.
HandMenu_ExampleScene 5

HandMenu_Large_AutoWorldLock_On_HandDrop

Det här exemplet liknar HandMenu_Large_WorldLock_On_GrabAndPull. Den enda skillnaden är att menyn automatiskt blir världslåst för hand. Det här beteendet hanteras genom att inte dölja händelsen MenuContent på OnLastHandLost(). Hämta & pull-beteende är samma som HandMenu_Large_WorldLock_On_GrabAndPull exempel.

Skript

Beteendet HandConstraint ger en lösning som begränsar det spårade objektet till en region som är säker för handbegränsat innehåll (till exempel handgränssnitt, menyer osv.). Säkra regioner betraktas som områden som inte korsar handen. En härledd klass med HandConstraint anropad HandConstraintPalmUp ingår också för att demonstrera ett vanligt beteende för att aktivera det lösenlösarspårade objektet när handflatan är riktad mot användaren.

Mer dokumentation finns i verktygstipsen som är tillgängliga för varje HandConstraint egenskap. Några egenskaper definieras mer detaljerat nedan.

HandMenu_ExampleScene Palm upp
  • Säker zon: Den säkra zonen anger var till hands innehållet ska begränsas. Vi rekommenderar att innehållet placeras på Ulnar-sidan för att undvika överlappning med handen och förbättrad interaktionskvalitet. Säkra zoner beräknas genom att ta handorienteringen projicerad i ett plan ortogonal till kamerans vy och raycasting mot en avgränsningslåda runt händerna. Säkra zoner definieras för att fungera med IMixedRealityHand men fungerar även med andra typer av kontrollanter. Vi rekommenderar att du utforskar vad varje säker zon representerar på olika typer av kontrollanter.

  • Följ hand tills den är riktad mot kameran Med den här inställningen aktiv kommer lösaren att följa handrotationen tills menyn är tillräckligt justerad med blicken, varefter den möter kameran. Det här beteendet fungerar genom att ändra SolverRotationBehavior i HandConstraintSolver, från LookAtTrackedObject till LookAtMainCamera när GazeAlignment-vinkeln med lösaren varierar.

HandMenu Säkra zoner
  • Aktiveringshändelser: Utlöser för närvarande HandConstraint fyra aktiveringshändelser. Dessa händelser kan användas i många olika kombinationer för att skapa unika HandConstraint beteenden, se HandBasedMenuExample-scenen under MRTK/Examples/Demos/HandTracking/Scenes/ exempel på dessa beteenden.

    • OnHandActivate: utlöses när en hand uppfyller IsHandActive-metoden.
    • OnHandDeactivate: utlöses när IsHandActive-metoden inte längre är nöjd.
    • OnFirstHandDetected: inträffar när tillståndet för handspårning ändras från inga händer i vyn till den första hand i vyn.
    • OnLastHandLost: inträffar när handspårningstillståndet ändras från minst en hand i vyn till inga händer i vyn.
  • Lösningsaktiverings-/inaktiveringslogik: För närvarande är rekommendationen för aktivering och inaktivering HandConstraintPalmUp av logik att göra det med hjälp av SolverHandlers UpdateSolver-värde i stället för att inaktivera/aktivera objektet. Det här beteendet kan ses i exempelscenen via de redigeringsbaserade krokar som utlöses efter den bifogade menyns ManipulationHandler-händelser "OnManipulationStarted/Ended".

    • Stoppa logiken för handbegränsning: När du försöker ange att det handbegränsade objektet ska stoppa (eller inte köra) aktiverings-/inaktiveringslogik anger du UpdateSolver till False i stället för att inaktivera HandConstraintPalmUp.
      • Om du vill aktivera den blickbaserade (eller till och med icke-blickbaserade) återkopplingslogiken följer du upp genom att anropa funktionen HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine(). Det här anropet utlöser en coroutine som sedan fortsätter att kontrollera om villkoret "IsValidController" är uppfyllt och ställer in UpdateSolver på Sant när det är (eller om objektet är inaktiverat).
    • Starta logiken för handbegränsning: När du försöker ange att det handbegränsade objektet ska börja följa din hand igen (baserat på om det uppfyller aktiveringskriterierna) anger du SolverHandlers UpdateSolver till true.
  • Återanslut logik: För närvarande HandConstraintPalmUp kan automatiskt återansluta målobjektet till den spårade punkten, oavsett om SolverHandlers UpdateSolver är Sant eller inte. Det här beteendet hanteras genom att anropa funktionen HandConstraintPalmUps StartWorldLockReattachCheckCoroutine() efter att den har varit världslåst (vilket i det här fallet effektivt ställer in SolverHandlers UpdateSolver på False).

Se även