Menu manual — MRTK2

Exemplo de UX do Menu Lateral

Os menus de mão permitem que os usuários ativem rapidamente a interface do usuário conectada com a mão para funções usadas com frequência. Para evitar a ativação falsa ao interagir com outros objetos, o menu manual fornece opções como 'Exigir Mão Simples' e 'Usar Ativação de Foco'. É recomendável usar essas opções para evitar a ativação indesejada.

Exemplos de menu manual

A cena HandMenuExamples.unity está na MRTK/Examples/Demos/HandTracking/Scenes pasta . Quando estiver em execução, a cena só ativará o tipo de menu selecionado no momento.
HandMenu_ExampleScene

Você pode encontrar esses pré-fabricados de menu manual na MRTK/Examples/Common/Prefabs pasta.

HandMenu_Small_HideOnHandDrop e HandMenu_Medium_HideOnHandDrop

Esses dois exemplos simplesmente ativam e desativam o objeto MenuContent para mostrar e ocultar o menu no evento OnFirstHandDetected() e OnLastHandLost().
HandMenu_ExampleScene 1
HandMenu_ExampleScene 2

HandMenu_Large_WorldLock_On_GrabAndPull

Para menus mais complexos que exigem tempo de interação mais longo, é recomendável bloquear o menu. Neste exemplo, o usuário pode pegar e efetuar pull para bloquear o menu, além de ativar e desativar os eventos MenuContent em OnFirstHandDetected() e OnLastHandLost().
HandMenu_ExampleScene 3

Backplate torna-o ManipulationHandler agarrável e móvel. No evento Manipulation Started , SolverHandler.UpdateSolvers é desativado para bloquear o menu. Além disso, ele mostra o botão Fechar para permitir que o usuário feche o menu quando a tarefa for concluída. No evento Manipulation Ended , ele chama HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine para permitir que o usuário traga o menu de volta à mão levantando e olhando para a palma da mão.
HandMenu_ExampleScene 4

O botão Fechar reativa SolverHandler.UpdateSolvers e oculta o MenuContent.
HandMenu_ExampleScene 5

HandMenu_Large_AutoWorldLock_On_HandDrop

Este exemplo é semelhante a HandMenu_Large_WorldLock_On_GrabAndPull. A única diferença é que o menu será bloqueado automaticamente na queda manual. Esse comportamento é tratado por não ocultar o evento MenuContent em OnLastHandLost(). Capturar & comportamento de pull é o mesmo que HandMenu_Large_WorldLock_On_GrabAndPull exemplo.

Scripts

O HandConstraint comportamento fornece um solucionador que restringe o objeto rastreado a uma região segura para conteúdo restrito à mão (como interface do usuário manual, menus etc.). Regiões seguras são consideradas áreas que não se cruzam com a mão. Uma classe derivada de HandConstraint chamada HandConstraintPalmUp também é incluída para demonstrar um comportamento comum de ativar o objeto controlado pelo solucionador quando a palma da mão estiver voltada para o usuário.

Confira as dicas de ferramenta disponíveis para cada HandConstraint propriedade para obter mais documentação. Algumas propriedades são definidas mais detalhadamente abaixo.

HandMenu_ExampleScene Palm para cima
  • Zona segura: a zona segura especifica onde, por sua vez, restringir o conteúdo. É recomendável que o conteúdo seja colocado no lado ulnar para evitar sobreposição com a mão e melhor qualidade de interação. Zonas seguras são calculadas levando a orientação das mãos projetada em um plano ortogonal para a exibição da câmera e raycasting contra uma caixa delimitadora ao redor das mãos. As zonas seguras são definidas para funcionar, IMixedRealityHand mas também funcionam com outros tipos de controlador. É recomendável explorar o que cada zona segura representa em diferentes tipos de controlador.

  • Siga a mão até a câmera voltada Com essa configuração ativa, o solucionador seguirá a rotação da mão até que o menu esteja suficientemente alinhado com o foco, momento em que ele fica voltado para a câmera. Esse comportamento funciona alterando o SolverRotationBehavior no HandConstraintSolver, de LookAtTrackedObject para LookAtMainCamera, pois o ângulo GazeAlignment com o solucionador varia.

Zonas seguras do HandMenu
  • Eventos de ativação: atualmente, o HandConstraint dispara quatro eventos de ativação. Esses eventos podem ser usados em muitas combinações diferentes para criar comportamentos exclusivos HandConstraint , consulte a cena MRTK/Examples/Demos/HandTracking/Scenes/ HandBasedMenuExample em para obter exemplos desses comportamentos.

    • OnHandActivate: dispara quando uma mão satisfaz o método IsHandActive.
    • OnHandDeactivate: dispara quando o método IsHandActive não é mais atendido.
    • OnFirstHandDetected: ocorre quando o estado de acompanhamento da mão muda de nenhuma mão no modo de exibição, para a primeira mão na exibição.
    • OnLastHandLost: ocorre quando o estado de acompanhamento da mão muda de pelo menos uma mão no modo de exibição, para nenhuma mão na exibição.
  • Lógica de Ativação/Desativação do Solver: atualmente, a recomendação para ativar e desativar HandConstraintPalmUp a lógica é fazer isso usando o valor UpdateSolver do SolverHandler, em vez de desabilitar/habilitar o objeto. Esse comportamento pode ser visto na cena de exemplo por meio dos ganchos baseados em editor disparados após os eventos "OnManipulationStarted/Ended" do menu anexado.

    • Interrompendo a lógica de restrição manual: ao tentar definir o objeto restrito à mão para interromper (ou não executar) a lógica de ativação/desativação, defina UpdateSolver como False em vez de desabilitar HandConstraintPalmUp.
      • Se você quiser habilitar a lógica de reanexamento baseada em foco (ou mesmo sem foco), siga chamando a função HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine(). Essa chamada disparará uma corrotina que continuará a marcar se os critérios "IsValidController" forem atendidos e definirão UpdateSolver como True quando ele estiver (ou o objeto estiver desabilitado).
    • Iniciando a lógica de restrição manual: ao tentar definir o objeto restrito à mão para começar a seguir sua mão novamente (com base em se ele atende aos critérios de ativação), defina UpdateSolver do SolverHandler como true.
  • Lógica de reanexação: atualmente, o HandConstraintPalmUp é capaz de reanexar automaticamente o objeto de destino ao ponto rastreado, independentemente de o UpdateSolver do SolverHandler ser True ou não. Esse comportamento é tratado por meio da chamada da função StartWorldLockReattachCheckCoroutine() do HandConstraintPalmUp, depois de ter sido bloqueada pelo mundo (que, nesse caso, está efetivamente definindo UpdateSolver do SolverHandler como False).

Confira também