Контроллеры, указатели и фокус — MRTK2

Контроллеры, указатели и фокус — это концепции более высокого уровня, основанные на основе основы, установленной основной системой ввода. Вместе они предоставляют большую часть механизма взаимодействия с объектами в сцене.

Контроллеры

Контроллеры представляют собой представления физического контроллера (6 градусов свободы, сформулированной руки и т. д.). Они создаются диспетчерами устройств и отвечают за взаимодействие с соответствующей базовой системой и перевод этих данных в данные и события в форме MRTK.

Например, на платформе WindowsMixedRealityArticulatedHand Windows Mixed Reality контроллер, отвечающий за взаимодействие с базовыми API-интерфейсами отслеживания рук Windows для получения сведений о суставах, позе и других свойствах руки. Он отвечает за преобразование этих данных в соответствующие события MRTK (например, путем вызова RaisePoseInputChanged или RaiseHandJointsUpdated) и путем обновления собственного внутреннего состояния, чтобы запросы на TryGetJointPose получение правильных данных возвращали правильные данные.

Как правило, жизненный цикл контроллера будет включать в себя:

  1. Контроллер создается диспетчером устройств при обнаружении нового источника (например, диспетчер устройств обнаруживает и начинает отслеживать руку).

  2. В цикле Update() контроллера он вызывает базовую систему API.

  3. В том же цикле обновления он вызывает изменения входных событий путем вызова непосредственно в основную систему ввода (например, вызов HandMeshUpdated или HandJointsUpdated).

Указатели и фокус

Указатели используются для взаимодействия с игровыми объектами. В этом разделе описывается, как создаются указатели, как они обновляются и как они определяют объекты, которые находятся в фокусе. Он также охватывает различные типы указателей, которые существуют, и сценарии, в которых они активны.

Категории указателей

Указатели обычно делятся на одну из следующих категорий:

  • Дальние указатели

    Эти типы указателей используются для взаимодействия с объектами, которые находятся далеко от пользователя (далеко определяется как просто "не близко"). Эти типы указателей обычно приведения линий, которые могут идти далеко в мир и позволяют пользователю взаимодействовать с объектами, которые не находятся непосредственно рядом с ними.

  • Рядом с указателями

    Эти типы указателей используются для взаимодействия с объектами, которые достаточно близки пользователю для захвата, касания и управления ими. Как правило, эти типы указателей взаимодействуют с объектами, выполняя поиск объектов в соседней близости (либо выполняя трансляцию на небольших расстояниях, выполняя сферическое приведение объектов в непосредственной близости, либо перечисляя списки объектов, которые считаются захватимыми или сенсорными).

  • Указатели телепорта

    Эти типы указателей подключаются к системе телепортации для обработки перемещения пользователя в расположение, предназначенное для указателя.

Посредник указателя

Так как один контроллер может иметь несколько указателей (например, сформулированная рука может иметь как близкие, так и дальние указатели взаимодействия), существует компонент, отвечающий за посредник, который должен быть активен.

Например, когда рука пользователя приближается к нажатой кнопке, ShellHandRayPointer она должна перестать отображаться и PokePointer должна быть задействована.

Это обрабатывается DefaultPointerMediator, который отвечает за определение активных указателей на основе состояния всех указателей. Одна из ключевых вещей, которые это делает, заключается в отключении дальних указателей, когда близкий указатель близко к объекту (см. раздел DefaultPointerMediator).

Можно предоставить альтернативную реализацию медиатора указателя, изменив PointerMediator свойство в профиле указателя.

Отключение указателей

Так как посредник указателя выполняет каждый кадр, он в конечном итоге контролирует активное или неактивное состояние всех указателей. Таким образом, если задать свойство IsInteractionEnabled указателя в коде, он будет перезаписан посредником указателя каждый кадр. Вместо этого можно указать, следует ли включить PointerBehavior или отключить указатели самостоятельно. Обратите внимание, что это будет работать только в том случае, если вы используете значение по умолчанию FocusProvider и DefaultPointerMediator в MRTK.

Пример. Отключение лучей рук в MRTK

Следующий код отключит лучи рук в MRTK:

// Turn off all hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);

// Turn off hand rays for the right hand only
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Right);

Следующий код возвращает лучи рук к их поведению по умолчанию в MRTK:

PointerUtils.SetHandRayPointerBehavior(PointerBehavior.Default);

Следующий код заставит лучи рук быть включено, независимо от того, находится ли рядом с захватом:

// Turn off all hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOn);

См PointerUtils . дополнительные TurnPointersOnOff примеры.

FocusProvider

Это FocusProvider рабочая лошадка, которая отвечает за итерацию по списку всех указателей и выяснить, что объект фокуса предназначен для каждого указателя.

В каждом Update() вызове выполняется следующее:

  1. Обновите все указатели, путем передачи лучей и обнаружения попаданий, настроенных самим указателем (например, указатель сферы может указать SphereOverlap raycastMode, поэтому FocusProvider будет выполнять столкновение на основе сферы).

  2. Обновите объект фокуса на основе указателя (т. е. если объект получил фокус, он также активирует события для этого объекта, если объект потерял фокус, он активирует потерю фокуса и т. д.).

Конфигурация указателя и жизненный цикл

Указатели можно настроить в разделе указателей в профиле системы ввода.

Время существования указателя обычно выполняется следующим образом:

  1. Диспетчер устройств обнаружит наличие контроллера. Затем этот диспетчер устройств создаст набор указателей, связанных с контроллером, с помощью вызова RequestPointers.

  2. FocusProvider в цикле Update() выполняет итерацию по всем допустимым указателям и выполняет связанную логику обнаружения лучей или попаданий. Он используется для определения объекта, ориентированного на каждый конкретный указатель.

    • Так как одновременно можно одновременно использовать несколько источников входных данных (например, две руки, активные), можно также иметь несколько объектов с фокусом одновременно.
  3. Диспетчер устройств, обнаружив, что источник контроллера был потерян, разорвет указатели, связанные с потерянным контроллером.