Sdílet prostřednictvím


Ruční nabídka — MRTK3

Ruční nabídka

Ruční nabídky umožňují uživatelům vyvolat ručně připojené uživatelské rozhraní pro často používané funkce. Obvykle se jedná o malé skupiny tlačítek , které nabízejí rychlé akce. Někdy jsou však uživateli k dispozici složitější rozložení pro zobrazení informací nebo nastavení jako nabídka rukou, často s možností "odtrhnout" nabídku od ruky a ukotvit ji ve světě.

Nabídka Hand (Vyžadovat plochou ruku) a Use Gaze Activation (Použít aktivaci pohledem) poskytuje možnosti Vyžadovat plochou ruku a Použít aktivaci pohledem, aby se zabránilo falešné aktivaci při interakci s jinými objekty. Doporučujeme použít tyto možnosti, abyste zabránili nežádoucí aktivaci.

Ukázková scéna a prefabs

Pokud používáte projekt šablony, HandMenuExamples.unity ukazuje několik běžných konfigurací pro ruční nabídky, a to všechny pomocí HandConstraintPalmUp skriptu.

Ukázková scéna nabídky hand

HandMenuLarge

Tento prefab ukazuje příklad velkého nebo složitého uživatelského rozhraní, které vyžaduje delší dobu interakce. Pro tento typ uživatelského rozhraní se doporučuje uzamknout nabídku po ruce, abyste zlepšili použitelnost a vyhnuli se únavě paží. Tento příklad také podporuje možnost "uchopte a zatáhněte" k uzamčení nabídky.

V tomto příkladu se nabídka stane viditelným a neviditelným aktivací objektu MenuContent na události OnFirstHandDetected(). U události OnLastHandLost() se aktivuje tlačítko Zavřít a aktivuje se animace umístění. Animace představuje jednoduché kolísání měřítka. Vzhledem k tomu, že jsme událost MenuContent onLastHandLost() neskryli, bude nabídka automaticky uzamčena světem, když nebude ruka viditelná. Hodnoty v části Dlaň nahoru byly optimalizovány tak, aby nabídka byla uzamčená po celém světě, aniž by byla příliš přetahována dolů při ručním přetažení.

Příklad hand menu large 1

Konfigurace dlaně nahoru

Tento příklad poskytuje uchopitelný pruh v dolní části nabídky a chování automatického uzamykání světa. Uživatel může explicitně odpojit nabídku od ruky a umístit ji do světa tak, že ji vezme. Abychom toho dosáhli, v události ManipulationStarted() v ObjectManipulatoru zakážeme SolverHandler.UpdateSolvers. V opačném případě nebude možné nabídku odpojit, protože řešitel HandConstraint se pokusí nabídku umístit do blízkosti pozice ruky. Používáme také HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine , abychom uživateli umožnili zvednout ruku a znovu připojit nabídku k ruce.

Příklad hand menu Large 2

A konečně, tlačítko zavřít musí znovu aktivovat SolverHandler.UpdateSolvers obnovit funkce handconstraint řešitele.

Příklad hand menu large 3

Skripty

Toto HandConstraint chování poskytuje řešitele, který omezuje sledovaný objekt na oblast bezpečnou pro ručně omezený obsah (například uživatelské rozhraní rukou, nabídky atd.). Bezpečné oblasti jsou považovány za oblasti, které se neprotínají s rukou. Je také zahrnuta odvozená třída HandConstraint s názvem HandConstraintPalmUp , která demonstruje běžné chování aktivace objektu sledovaného řešitelem, když je dlaň směrem k uživateli.

Další dokumentaci najdete v popisech dostupných pro každou HandConstraint vlastnost. Několik vlastností je definováno podrobněji níže.

  • Bezpečná zóna: Bezpečná zóna určuje, kde se má omezit obsah. Doporučuje se umístit obsah na ulnarovou stranu, aby se zabránilo překrývání s rukou a zlepšila se kvalita interakce. Bezpečné zóny se vypočítají podle orientace rukou promítaného do roviny ortogonální na pohled kamery a paprskování proti ohraničující rámeček kolem rukou. Bezpečné zóny jsou definovány pro práci s XRNode. Doporučujeme prozkoumat, co každá bezpečná zóna představuje na různých typech kontroleru.

  • Řiďte se rukou, dokud se nesmáhá kamera. Když je tato aktivní, řešitel bude sledovat otáčení rukou, dokud nabídka nebude dostatečně zarovnaná s pohledem na kameru. Aby to fungovalo, změňte SolverRotationBehavior v HandConstraintSolversouboru LookAtTrackedObject z na LookAtMainCamera , protože GazeAlignment úhel s řešitelem se liší.

Příklad bezpečné zóny v nabídce hand

  • Události aktivace: V současné době aktivuje HandConstraint čtyři události aktivace. Tyto události lze použít v mnoha různých kombinacích k vytvoření jedinečného HandConstraint chování.

    • OnHandActivate: aktivuje, když ruka splňuje metodu IsHandActive.
    • OnHandDeactivate: aktivuje se, když už není metoda IsHandActive spokojená.
    • OnFirstHandDetected: Nastává, když se stav sledování rukou změní z žádné ruky v zobrazení na první ruku v zobrazení.
    • OnLastHandLost: nastane, když se stav sledování rukou změní z alespoň jedné ruky v zobrazení na žádné ruce v zobrazení.
  • Logika aktivace/deaktivace řešitele: V současné době se doporučuje aktivovat a deaktivovat HandConstraintPalmUp logiku tak, SolverHandlerže použijete hodnotu ", UpdateSolver nikoli zakázání/povolení objektu. To je vidět v ukázkové scéně prostřednictvím hooků založených na editoru aktivovaných po událostech "OnManipulationStarted/Ended" připojené nabídky ManipulationHandler.

    • Zastavení logiky ručního omezení: Při pokusu o zastavení objektu s ručním omezením (a nespouštět logiku aktivace/deaktivace) nastavte UpdateSolver na False a nezakazujte HandConstraintPalmUp.
      • Pokud chcete povolit logiku opětovného připojení založeného na pohledu (nebo dokonce bez pohledu), následuje volání HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine() funkce. Tím se aktivuje korutin, který bude dál kontrolovat, jestli jsou splněná kritéria ,IsValidController a jakmile je nastavená hodnota UpdateSolver na Hodnotu True (nebo je objekt zakázaný).
    • Spuštění logiky hand-constraint: Při pokusu o nastavení objektu s omezením ruky tak, aby znovu začal sledovat vaši ruku (na základě toho, jestli splňuje kritéria aktivace), nastavte UpdateSolver obslužné rutiny Řešitele na hodnotu true.
  • Logika opětovného připojení: V současné době HandConstraintPalmUp může objekt automaticky znovu připojit cílový objekt ke sledovanému bodu bez ohledu na to, zda SolverHandlerUpdateSolver jsou hodnoty true. To se provádí voláním HandConstraintPalmUpfunkce po StartWorldLockReattachCheckCoroutine() uzamčení světem (což v tomto případě ve skutečnosti nastavuje UpdateSolver obslužné rutiny řešitele na hodnotu False).