Жесты в Unity

Существует два основных способа выполнения действий при взгляде в Unity: жесты рук и контроллеры движения в HoloLens и иммерсивном HMD. Доступ к данным для обоих источников пространственного ввода осуществляется через одни и те же API в Unity.

Unity предоставляет два основных способа доступа к пространственным входным данным для Windows Mixed Reality. Общие API Input.GetButton/Input.GetAxis работают в нескольких пакетах SDK XR для Unity, а API InteractionManager/GestureRecognizer, характерный для Windows Mixed Reality, предоставляет полный набор пространственных входных данных.

Высокоуровневые API составных жестов (GestureRecognizer)

Пространство имен:UnityEngine.XR.WSA.Input
Типы: GestureRecognizer, GestureSettings, InteractionSourceKind

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

Каждое событие Жеста в GestureRecognizer предоставляет SourceKind для входных данных, а также луч головы нацеливания на момент события. Некоторые события предоставляют дополнительные сведения, относящиеся к контексту.

Для захвата жестов с помощью Распознавателя жестов необходимо выполнить всего несколько действий:

  1. Создание распознавателя жестов
  2. Укажите жесты для watch
  3. Подписка на события для этих жестов
  4. Начало захвата жестов

Создание распознавателя жестов

Чтобы использовать GestureRecognizer, необходимо создать GestureRecognizer:

GestureRecognizer recognizer = new GestureRecognizer();

Укажите жесты для watch

Укажите интересующие вас жесты с помощью SetRecognizableGestures():

recognizer.SetRecognizableGestures(GestureSettings.Tap | GestureSettings.Hold);

Подписка на события для этих жестов

Подпишитесь на события для интересующих вас жестов.

void Start()
{
    recognizer.Tapped += GestureRecognizer_Tapped;
    recognizer.HoldStarted += GestureRecognizer_HoldStarted;
    recognizer.HoldCompleted += GestureRecognizer_HoldCompleted;
    recognizer.HoldCanceled += GestureRecognizer_HoldCanceled;
}

Примечание

Жесты навигации и манипуляции являются взаимоисключающими в экземпляре GestureRecognizer.

Начало захвата жестов

По умолчанию GestureRecognizer не отслеживает входные данные, пока не будет вызван метод StartCapturingGestures(). Возможно, событие жеста может быть создано после вызова Метода StopCapturingGestures(), если входные данные были выполнены до кадра, в котором была обработана операция StopCapturingGestures(). Средство GestureRecognizer будет запоминать, был ли он включен или выключен во время предыдущего кадра, в котором был фактически выполнен жест, поэтому его можно запускать и останавливать мониторинг жестов на основе нацеливания взгляда этого кадра.

recognizer.StartCapturingGestures();

Остановка захвата жестов

Чтобы остановить распознавание жестов, выполните приведенные далее действия.

recognizer.StopCapturingGestures();

Удаление распознавателя жестов

Не забудьте отменить подписку на подписанные события перед уничтожением объекта GestureRecognizer .

void OnDestroy()
{
    recognizer.Tapped -= GestureRecognizer_Tapped;
    recognizer.HoldStarted -= GestureRecognizer_HoldStarted;
    recognizer.HoldCompleted -= GestureRecognizer_HoldCompleted;
    recognizer.HoldCanceled -= GestureRecognizer_HoldCanceled;
}

Отрисовка модели контроллера движения в Unity

Модель контроллера движения и телепортация
Модель контроллера движения и телепортация

Для отрисовки контроллеров движения в приложении, которые соответствуют физическим контроллерам, которые пользователи удерживают и сформулируют при нажатии различных кнопок, можно использовать заготовку MotionController в наборе средств Смешанная реальность. Этот заготовка динамически загружает правильную модель glTF во время выполнения из установленного в системе драйвера контроллера движения. Важно загружать эти модели динамически, а не импортировать их вручную в редакторе, чтобы приложение отображало физически точные трехмерные модели для любых текущих и будущих контроллеров, которые могут иметь ваши пользователи.

  1. Следуйте инструкциям начало работы, чтобы скачать набор средств Смешанная реальность и добавить его в проект Unity.
  2. Если вы заменили камеру на заготовку MixedRealityCameraParent в рамках начало работы шагов, вы можете пойти! Этот заготовка включает отрисовку контроллера движения. В противном случае добавьте Assets/HoloToolkit/Input/Prefabs/MotionControllers.prefab в сцену из области Проекта. Вы хотите добавить эту заготовку в качестве дочернего объекта любого родительского объекта, используемого для перемещения камеры, когда пользователь телепортируется в сцене, чтобы контроллеры были вместе с пользователем. Если ваше приложение не включает телепортирование, просто добавьте заготовку в корне сцены.

Создание объектов

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

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

  • Используйте скорость контроллера вместо положения. В ноябрьском обновлении для Windows мы внесли изменения в поведение в состоянии отслеживания позиционного отслеживания "Приблизительно". В этом состоянии сведения о скорости контроллера будут по-прежнему сообщаться до тех пор, пока мы считаем, что его высокая точность, которая часто дольше, чем позиция остается высокой точностью.

  • Включите угловую скорость контроллера. Вся эта логика содержится в throwing.cs файле статического GetThrownObjectVelAngVel метода в пакете, связанном выше:

    1. При сохранении угловой скорости вызываемый объект должен поддерживать ту же угловую скорость, что и в момент броска: objectAngularVelocity = throwingControllerAngularVelocity;

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

      Vector3 radialVec = thrownObjectCenterOfMass - throwingControllerPos;
      Vector3 tangentialVelocity = Vector3.Cross(throwingControllerAngularVelocity, radialVec);
      
    3. Общая скорость бросаемого объекта — это сумма скорости контроллера и этой тангенциальной скорости: objectVelocity = throwingControllerVelocity + tangentialVelocity;

  • Обратите особое внимание на время применения скорости. При нажатии кнопки может потребоваться до 20 мс, чтобы это событие перенаплылось через Bluetooth в операционную систему. Это означает, что при опросе изменения состояния контроллера с нажатого на без нажатия или наоборот, сведения о позе контроллера, полученные с ним, на самом деле будут опережать это изменение состояния. Кроме того, поза контроллера, представленная нашим API опроса, по прогнозам, отражает вероятную позу в момент отображения кадра, которая может быть более 20 мс в будущем. Это хорошо подходит для отрисовки удерживаемых объектов, но усугубляет нашу проблему времени для нацеливания на объект, так как мы вычисляем траекторию на момент, когда пользователь выпустил бросок. К счастью, в ноябрьском обновлении при отправке события Unity, такого как InteractionSourcePressed или InteractionSourceReleased , состояние включает исторические данные о позе сзади, когда кнопка была нажата или отпущена. Чтобы получить наиболее точную отрисовку контроллера и нацеливание на контроллер во время бросков, необходимо правильно использовать опрос и обработку событий.

    • Для отрисовки каждого кадра в контроллере приложение должно располагать GameObject контроллера в позиции контроллера с прогнозом на момент фотона текущего кадра. Эти данные можно получить из API опроса Unity, таких как XR. InputTracking.GetLocalPosition или XR. WSA. Input.InteractionManager.GetCurrentReading.
    • Для контроллера, нацеливающегося на нажатие или выпуск, ваше приложение должно выполнять луч и вычислять траектории на основе исторической позиции контроллера для этого события нажатия или выпуска. Эти данные можно получить из API-интерфейсов событий Unity, таких как InteractionManager.InteractionSourcePressed.
  • Используйте позу захвата. Angular скорость и скорость отображаются относительно положения захвата, а не позы указателя.

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

Контроллеры жестов и движений в MRTK

Вы можете получить доступ к жестам и контроллеру движения из диспетчера ввода.

Обучение по руководствам

Пошаговые руководства с более подробными примерами настройки доступны в Смешанная реальность Академии:

Входные данные смешанной реальности 213 — контроллер движения
Входные данные смешанной реальности 213 — контроллер движения

Следующий этап разработки

Если вы следите за путь разработки Unity, который мы изложили, вы находитесь в разгаре изучения основных стандартных блоков MRTK. Отсюда вы можете перейти к следующему стандартному блоку:

Или перейдите к возможностям и API платформы смешанной реальности:

Вы можете в любой момент вернуться к этапам разработки для Unity.

См. также статью