Menu manual — MRTK2
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.
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_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().
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.
O botão Fechar reativa SolverHandler.UpdateSolvers e oculta o MenuContent.
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.
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.
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 exclusivosHandConstraint
, consulte a cenaMRTK/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.
- 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.
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).