Меню руки — MRTK2

Пример интерфейса меню руки

Меню руки позволяет пользователям быстро вызывать пользовательский интерфейс для часто используемых функций. Чтобы предотвратить ложную активацию при взаимодействии с другими объектами, в меню руки есть такие параметры, как "Требовать плоскую руку" и "Использовать активацию взгляда". Рекомендуется использовать эти параметры для предотвращения нежелательной активации.

Примеры меню "Руки"

Сцена HandMenuExamples.unity находится в папке MRTK/Examples/Demos/HandTracking/Scenes . При запуске сцена активирует только выбранный в данный момент тип меню.
HandMenu_ExampleScene

Эти заготовки меню для рук можно найти в папке MRTK/Examples/Common/Prefabs .

HandMenu_Small_HideOnHandDrop и HandMenu_Medium_HideOnHandDrop

Эти два примера просто активируют и деактивируют объект MenuContent для отображения и скрытия меню в событиях OnFirstHandDetected() и OnLastHandLost( ).
HandMenu_ExampleScene 1
HandMenu_ExampleScene 2

HandMenu_Large_WorldLock_On_GrabAndPull

Для более сложных меню, требующих больше времени взаимодействия, рекомендуется заблокировать меню. В этом примере пользователь может захватывать и извлекать меню с блокировкой мира, а также активировать и деактивировать MenuContent в событиях OnFirstHandDetected() и OnLastHandLost( ).
HandMenu_ExampleScene 3

Backplate ManipulationHandler делает его захватимым и перемещаемым. В событии "Начало манипуляции" функция SolverHandler.UpdateSolvers отключена, чтобы заблокировать меню. Кроме того, отображается кнопка Закрыть , позволяющая пользователю закрыть меню после завершения задачи. Событие Manipulation Ended вызывает HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine , чтобы пользователь вернул меню в руки, подняв и взглянув на ладонь.
HandMenu_ExampleScene 4

Кнопка "Закрыть " повторно активирует SolverHandler.UpdateSolvers и скрывает MenuContent.
HandMenu_ExampleScene 5

HandMenu_Large_AutoWorldLock_On_HandDrop

Этот пример аналогичен HandMenu_Large_WorldLock_On_GrabAndPull. Единственное отличие заключается в том, что меню будет автоматически заблокировано на рукой падение. Это поведение обрабатывается, не скрывая событие MenuContent on OnLastHandLost(). Поведение захвата & по запросу аналогично HandMenu_Large_WorldLock_On_GrabAndPull примере.

Скрипты

Поведение HandConstraint предоставляет решатель, который ограничивает отслеживаемый объект областью, безопасной для содержимого с ограниченными руками (например, пользовательский интерфейс, меню и т. д.). Безопасными считаются области, которые не пересекаются с рукой. Производный класс HandConstraint, вызываемый HandConstraintPalmUp, также включен для демонстрации общего поведения активации объекта, отслеживаемого решателем, когда ладонь обращена к пользователю.

Дополнительные сведения см. в подсказках по каждому HandConstraint свойству. Ниже приведены более подробные описания некоторых свойств.

HandMenu_ExampleScene Ладонь вверх
  • Безопасная зона. Безопасная зона указывает, где на руке нужно ограничить содержимое. Рекомендуется размещать содержимое на стороне Ulnar, чтобы избежать перекрытия с рукой и улучшения качества взаимодействия. Безопасные зоны вычисляются путем принятия ориентации рук, проецируемых в плоскость ортогонального представления камеры, и лучевого вещания на ограничивающий прямоугольник вокруг рук. Безопасные зоны определяются для работы с IMixedRealityHand , но и с другими типами контроллеров. Рекомендуется изучить, что представляет каждая безопасная зона в разных типах контроллеров.

  • Следите за рукой до лицом камеры Если этот параметр активен, решатель будет следовать повороту руки до тех пор, пока меню не будет достаточно выровнено с взглядом, в этот момент он обращен к камере. Это поведение работает путем изменения SolverRotationBehavior в HandConstraintSolver с LookAtTrackedObject на LookAtMainCamera, так как угол GazeAlignment с решателем изменяется.

Безопасные зоны HandMenu
  • События активации. В настоящее HandConstraint время активирует четыре события активации. Эти события можно использовать в различных сочетаниях для создания уникальных HandConstraint поведений. Примеры этих поведений см. в сцене HandBasedMenuExample в разделе MRTK/Examples/Demos/HandTracking/Scenes/ .

    • OnHandActivate: активируется, когда рука удовлетворяет методу IsHandActive.
    • OnHandDeactivate: активируется, если метод IsHandActive больше не удовлетворяется.
    • OnFirstHandDetected: происходит, когда состояние отслеживания рук меняется с без рук в поле зрения, на вид из первой руки.
    • OnLastHandLost: происходит, когда состояние отслеживания рук изменяется с по крайней мере с одной руки в представлении на нет рук в поле зрения.
  • Логика активации и деактивации решателя. В настоящее время рекомендуется активировать и деактивировать HandConstraintPalmUp логику с помощью значения UpdateSolver SolverHandler, а не путем отключения или включения объекта. Это поведение можно увидеть в примере сцены с помощью обработчиков на основе редактора, активированных после событий ManipulationHandler вложенного меню OnManipulationStarted/Ended.

    • Остановка логики ограничения рук. При попытке задать объект с ограничением руки для остановки (или не запуска) логики активации или деактивации установите для updateSolver значение False, а не отключать HandConstraintPalmUp.
      • Если вы хотите включить логику повторного подключения на основе взгляда (или даже не на основе взгляда), затем вызовите функцию HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine(). Этот вызов активирует сопрограмму, которая затем продолжает проверка, если условие IsValidController выполнено, и установит для UpdateSolver значение True после того, как это будет установлено (или объект отключен).
    • Запуск логики ограничения рук. При попытке задать объект с ограниченными руками, чтобы он снова начал следовать за рукой (в зависимости от того, соответствует ли он условиям активации), установите для Свойства SolverHandler UpdateSolver значение true.
  • Логика повторного подключения. В настоящее HandConstraintPalmUp время может автоматически повторно подключить целевой объект к отслеживаемой точке, независимо от того, имеет ли значение UpdateSolver для SolverHandler значение True или нет. Это поведение обрабатывается путем вызова функции StartWorldLockReattachCheckCoroutine() HandConstraintPalmUp после того, как она будет заблокирована во всем мире (что в данном случае фактически устанавливает для Свойства SolverHandler UpdateSolver значение False).

См. также раздел