HoloLens (1-го поколения) Ввод 211: жест

Важно!

Учебники по Смешанная реальность Академии были разработаны с учетом HoloLens (1-го поколения), Unity 2017 и Смешанная реальность иммерсивные гарнитуры. Поэтому мы считаем, что важно оставить эти руководства для разработчиков, которые ищут рекомендации по разработке для этих устройств. Эти руководства не будут обновлены с помощью последних наборов инструментов или взаимодействий, используемых для HoloLens 2, и могут быть несовместимы с более новыми версиями Unity. Они будут сохранены для работы на поддерживаемых устройствах. Опубликован новый цикл руководств для HoloLens 2.

Жесты превратить намерение пользователя в действие. С помощью жестов пользователи могут взаимодействовать с голограммами. В этом курсе мы узнаем, как отслеживать руки пользователя, реагировать на введенные пользователем данные и отправлять отзывы пользователю на основе состояния руки и расположения.

В MR Basics 101 мы использовали простой жест касания воздуха для взаимодействия с голограммами. Теперь мы перейдем за рамки жеста касания воздуха и рассмотрим новые концепции, чтобы:

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

В этом курсе мы вернемся к обозревателе моделей проектов Unity, который мы создали в MR Input 210. Наш друг астронавта вернулся, чтобы помочь нам в изучении этих новых концепций жестов.

Важно!

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

Поддержка устройств

Курс HoloLens Иммерсивные гарнитуры
211. Ввод в смешанной реальности: жесты ✔️ ✔️

Прежде чем начать

Предварительные условия

Файлы проекта

  • Скачайте файлы , необходимые для проекта. Требуется Unity 2017.2 или более поздней версии.
  • Распакуйте файлы на рабочем столе или в другом удобном расположении.

Примечание

Если вы хотите просмотреть исходный код перед скачиванием, он доступен на GitHub.

Эррата и примечания

  • Параметр "Включить только мой код" необходимо отключить (снять) в Visual Studio в разделе Tools-Options-Debugging>>, чтобы попасть в точки останова в коде.

Глава 0. Настройка Unity

Instructions

  1. Запустите Unity.
  2. Щелкните Open(Открыть).
  3. Перейдите в папку "Жест" , к которой вы ранее не архивировались.
  4. Найдите и выберите папку Обозревателя StartingModel/.
  5. Нажмите кнопку "Выбрать папку ".
  6. На панели Project разверните папку "Сцены".
  7. Дважды щелкните сцену ModelExplorer , чтобы загрузить ее в Unity.

Сборка

  1. В Unity выберите Параметры сборки файлов>.
  2. Если сцены или ModelExplorer не указаны в сценах в сборке, нажмите кнопку "Добавить открытые сцены ", чтобы добавить сцену.
  3. Если вы разрабатываете специально для HoloLens, задайте для целевого устройствазначение HoloLens. В противном случае оставьте его на любом устройстве.
  4. Убедитесь, что для типа сборки задано значение D3D , а для пакета SDK установлено последнее значение (пакет SDK 16299 или более поздней версии).
  5. Щелкните Построить.
  6. Создайте новую папку с именем App.
  7. Щелкните папку приложения одним щелчком.
  8. Нажмите кнопку "Выбрать папку", и Unity начнет создание проекта для Visual Studio.

По завершении работы Unity появится окно проводник.

  1. Откройте папку приложения .
  2. Откройте решение modelExplorer Visual Studio.

При развертывании в HoloLens:

  1. С помощью верхней панели инструментов в Visual Studio измените целевой объект с отладки на выпуск и с ARM на x86.
  2. Щелкните стрелку раскрывающегося списка рядом с кнопкой "Локальный компьютер" и выберите "Удаленный компьютер".
  3. Введите IP-адрес устройства HoloLens и установите для режима проверки подлинности универсальный (незашифрованный протокол). Нажмите кнопку Выбрать. Если вы не знаете IP-адрес устройства, просмотрите Параметры > дополнительные параметры сети & в Интернете>.
  4. В верхней строке меню нажмите кнопку "Отладка —> Начать без отладки " или нажмите клавиши CTRL+F5. Если это первый раз при развертывании на устройстве, необходимо связать его с Visual Studio.
  5. Когда приложение развернуто, закройте поле Fitbox с помощью жеста выбора.

При развертывании на иммерсивной гарнитуре:

  1. С помощью верхней панели инструментов в Visual Studio измените целевой объект с отладки на выпуск и с ARM на x64.
  2. Убедитесь, что целевой объект развертывания имеет значение "Локальный компьютер".
  3. В верхней строке меню нажмите кнопку "Отладка —> Начать без отладки " или нажмите клавиши CTRL+F5.
  4. После развертывания приложения закройте Fitbox , вытащив триггер на контроллер движения.

Примечание

На панели "Ошибки Visual Studio" могут появиться красные ошибки. Безопасно игнорировать их. Перейдите на панель вывода для просмотра фактического хода выполнения сборки. Ошибки на панели вывода потребуют исправления (чаще всего они вызваны ошибкой в скрипте).

Глава 1. Обратная связь, обнаруженная вручную

Задачи

  • Подпишитесь на события отслеживания рук.
  • Используйте обратную связь курсора для отображения пользователей при отслеживании руки.

Примечание

На HoloLens 2, руки обнаружили пожары всякий раз, когда руки видны (а не только когда пальцем указывает вверх).

Instructions

  • На панели Hierarchy разверните объект InputManager .
  • Найдите и выберите объект GesturesInput .

Скрипт InteractionInputSource.cs выполняет следующие действия:

  1. Подписывается на события InteractionSourceDetected и InteractionSourceLost.
  2. Задает состояние HandDetected.
  3. Отменяет подписку на события InteractionSourceDetected и InteractionSourceLost.

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

  1. На панели "Иерархия " выберите объект Cursor и удалите его.
  2. На панели Project найдите CursorWithFeedback и перетащите его на панель "Иерархия".
  3. Щелкните InputManager на панели "Иерархия", а затем перетащите объект CursorWithFeedback из hierarchy в поле курсораSimpleSinglePointerSelector InputManager в нижней части инспектора.
  4. Щелкните cursorWithFeedback в иерархии.
  5. На панели Inspector разверните сведения о состоянии курсора в скрипте курсора объекта .

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

  • Любое состояние наблюдения означает, что рука не обнаружена, и пользователь просто смотрит вокруг.
  • Любое состояние взаимодействия означает, что обнаружена рука или контроллер.
  • Любое состояние наведения означает , что пользователь смотрит на голограмму.

Построение и Развертывание

  • В Unity используйте Параметры сборки файлов > для перестроения приложения.
  • Откройте папку приложения .
  • Если она еще не открыта, откройте решение ModelExplorer Visual Studio.
    • (Если вы уже создали или развернули этот проект в Visual Studio во время настройки, вы можете открыть этот экземпляр VS и щелкнуть "Перезагрузить все" при появлении запроса).
  • В Visual Studio нажмите кнопку "Отладка — Начать без> отладки" или нажмите клавиши CTRL+F5.
  • После развертывания приложения в HoloLens закройте поле fitbox с помощью жеста касания воздуха.
  • Переместите руку в вид и наведите указательный палец на небо, чтобы начать отслеживание рук.
  • Переместите руку влево, вправо, вверх и вниз.
  • Посмотрите, как курсор изменяется при обнаружении руки, а затем теряется из представления.
  • Если вы используете иммерсивную гарнитуру, вам придется подключиться и отключить контроллер. Эта обратная связь становится менее интересной на иммерсивном устройстве, так как подключенный контроллер всегда будет "доступен".

Глава 2. Навигация

Задачи

  • Используйте события жестов навигации для поворота астронавта.

Instructions

Чтобы использовать жесты навигации в нашем приложении, мы изменим файл GestureAction.cs для поворота объектов при выполнении жеста навигации. Кроме того, мы добавим обратную связь к курсору для отображения при доступности навигации.

  1. На панели "Иерархия " разверните cursorWithFeedback.
  2. В папке Голограммы найдите ресурс ScrollFeedback.
  3. Перетащите префаб ScrollFeedback на объект GameObject CursorWithFeedback в иерархии.
  4. Щелкните CursorWithFeedback.
  5. На панели инспектора нажмите кнопку "Добавить компонент ".
  6. В меню введите в поле поиска CursorFeedback. Выберите результат поиска.
  7. Перетащите объект ScrollFeedback из иерархии в свойство Scroll Detected Game Object в компоненте "Обратная связь курсора " в инспекторе.
  8. На панели Hierarchy выберите объект AstroMan .
  9. На панели инспектора нажмите кнопку "Добавить компонент ".
  10. В меню введите действие жеста в поле поиска. Выберите результат поиска.

Затем откройте Файл GestureAction.cs в Visual Studio. В упражнении по написанию кода 2.c измените скрипт, чтобы сделать следующее:

  1. Поворот объекта AstroMan при каждом выполнении жеста навигации.
  2. Вычислите объект rotationFactor , чтобы управлять объемом поворота, примененным к объекту.
  3. Поворот объекта вокруг оси Y, когда пользователь перемещает руку влево или вправо.

Выполните упражнения по написанию кода 2.c в скрипте или замените код готовым решением ниже:

using HoloToolkit.Unity.InputModule;
using UnityEngine;

/// <summary>
/// GestureAction performs custom actions based on
/// which gesture is being performed.
/// </summary>
public class GestureAction : MonoBehaviour, INavigationHandler, IManipulationHandler, ISpeechHandler
{
    [Tooltip("Rotation max speed controls amount of rotation.")]
    [SerializeField]
    private float RotationSensitivity = 10.0f;

    private bool isNavigationEnabled = true;
    public bool IsNavigationEnabled
    {
        get { return isNavigationEnabled; }
        set { isNavigationEnabled = value; }
    }

    private Vector3 manipulationOriginalPosition = Vector3.zero;

    void INavigationHandler.OnNavigationStarted(NavigationEventData eventData)
    {
        InputManager.Instance.PushModalInputHandler(gameObject);
    }

    void INavigationHandler.OnNavigationUpdated(NavigationEventData eventData)
    {
        if (isNavigationEnabled)
        {
            /* TODO: DEVELOPER CODING EXERCISE 2.c */

            // 2.c: Calculate a float rotationFactor based on eventData's NormalizedOffset.x multiplied by RotationSensitivity.
            // This will help control the amount of rotation.
            float rotationFactor = eventData.NormalizedOffset.x * RotationSensitivity;

            // 2.c: transform.Rotate around the Y axis using rotationFactor.
            transform.Rotate(new Vector3(0, -1 * rotationFactor, 0));
        }
    }

    void INavigationHandler.OnNavigationCompleted(NavigationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void INavigationHandler.OnNavigationCanceled(NavigationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void IManipulationHandler.OnManipulationStarted(ManipulationEventData eventData)
    {
        if (!isNavigationEnabled)
        {
            InputManager.Instance.PushModalInputHandler(gameObject);

            manipulationOriginalPosition = transform.position;
        }
    }

    void IManipulationHandler.OnManipulationUpdated(ManipulationEventData eventData)
    {
        if (!isNavigationEnabled)
        {
            /* TODO: DEVELOPER CODING EXERCISE 4.a */

            // 4.a: Make this transform's position be the manipulationOriginalPosition + eventData.CumulativeDelta
        }
    }

    void IManipulationHandler.OnManipulationCompleted(ManipulationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void IManipulationHandler.OnManipulationCanceled(ManipulationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void ISpeechHandler.OnSpeechKeywordRecognized(SpeechEventData eventData)
    {
        if (eventData.RecognizedText.Equals("Move Astronaut"))
        {
            isNavigationEnabled = false;
        }
        else if (eventData.RecognizedText.Equals("Rotate Astronaut"))
        {
            isNavigationEnabled = true;
        }
        else
        {
            return;
        }

        eventData.Use();
    }
}

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

Построение и Развертывание

  1. Перестройте приложение в Unity, а затем выполните сборку и развертывание из Visual Studio, чтобы запустить его в HoloLens.
  2. Взгляд на астронавта должна появиться две стрелки на обеих сторонах курсора. Этот новый визуальный элемент указывает, что астронавт может быть повернут.
  3. Поместите руку в готовую позицию (указательный палец, указывающий на небо), так что HoloLens начнет отслеживать вашу руку.
  4. Чтобы повернуть астронавта, опустите указательный палец на позицию сцепляния, а затем переместите руку влево или вправо, чтобы активировать жест NavigationX.

Глава 3. Руководство по рукам

Задачи

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

Instructions

  1. На панели hierarchy выберите объект CursorWithFeedback .
  2. На панели инспектора нажмите кнопку "Добавить компонент ".
  3. В меню введите в поле " Руководство по руке". Выберите результат поиска.
  4. На панели ProjectГолограммы найдите ресурс HandGuidanceFeedback.
  5. Перетащите ресурс HandGuidanceFeedback на свойство индикатора управления рукой на панели инспектора .

Построение и Развертывание

  • Перестройте приложение в Unity, а затем выполните сборку и развертывание из Visual Studio для взаимодействия с приложением на HoloLens.
  • Поднимите руку в представление и поднимайте указательный палец, чтобы отследить.
  • Начните поворачивать астронавта с помощью жеста навигации (сжать указательный палец и большой палец вместе).
  • Переместите руку влево, вправо, вверх и вниз.
  • Когда ваша рука приближается к краю рамки жеста, стрелка должна появиться рядом с курсором, чтобы предупредить, что отслеживание рук будет потеряно. Стрелка указывает направление перемещения руки, чтобы предотвратить потерю отслеживания.

Глава 4. Манипуляция

Задачи

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

Instructions

GestureManager.cs и AstronautManager.cs позволят нам выполнить следующие действия:

  1. Используйте ключевое слово "Переместить астронавта", чтобы включить жесты манипуляции и "Повернуть астронавта", чтобы отключить их.
  2. Переключитесь на реагирование на распознаватель жестов манипуляции.

Итак, начнем.

  1. На панели "Иерархия " создайте пустой gameObject. Назовите его "AstronautManager".
  2. На панели инспектора нажмите кнопку "Добавить компонент ".
  3. В меню введите в поле поиска диспетчер астронавтов. Выберите результат поиска.
  4. На панели инспектора нажмите кнопку "Добавить компонент ".
  5. В меню введите источник ввода речи в поле поиска. Выберите результат поиска.

Теперь мы добавим речевые команды, необходимые для управления состоянием взаимодействия астронавта.

  1. Разверните раздел "Ключевые слова" в инспекторе.
  2. + Щелкните справа, чтобы добавить новое ключевое слово.
  3. Введите ключевое слово в качестве астронавта перемещения. При желании вы можете добавить сочетание клавиш.
  4. + Щелкните справа, чтобы добавить новое ключевое слово.
  5. Введите ключевое слово в качестве поворота астронавта. При желании вы можете добавить сочетание клавиш.
  6. Соответствующий код обработчика можно найти в файле GestureAction.cs в обработчике ISpeechHandler.OnSpeechKeywordRecognized .

How to set-up the Speech Input Source for chapter 4

Далее мы настроим обратную связь о манипуляциях на курсоре.

  1. На панели Project Голограммы найдите ресурс PathingFeedback.
  2. Перетащите префаб PathingFeedback на объект CursorWithFeedback в иерархии.
  3. На панели иерархии щелкните CursorWithFeedback.
  4. Перетащите объект PathingFeedback из иерархии в свойство Pathing Detected Game Object в компоненте "Обратная связь курсора " в инспекторе.

Теперь необходимо добавить код в Файл GestureAction.cs , чтобы включить следующее:

  1. Добавьте код в функцию IManipulationHandler.OnManipulationUpdated , которая перемещает астронавта при обнаружении жеста манипуляции .
  2. Вычислите вектор движения , чтобы определить, куда следует переместить астронавта на основе положения руки.
  3. Переместите астронавта на новую позицию.

Выполните упражнение по написанию кода 4.a в Файле GestureAction.cs или используйте готовое решение ниже:

using HoloToolkit.Unity.InputModule;
using UnityEngine;

/// <summary>
/// GestureAction performs custom actions based on
/// which gesture is being performed.
/// </summary>
public class GestureAction : MonoBehaviour, INavigationHandler, IManipulationHandler, ISpeechHandler
{
    [Tooltip("Rotation max speed controls amount of rotation.")]
    [SerializeField]
    private float RotationSensitivity = 10.0f;

    private bool isNavigationEnabled = true;
    public bool IsNavigationEnabled
    {
        get { return isNavigationEnabled; }
        set { isNavigationEnabled = value; }
    }

    private Vector3 manipulationOriginalPosition = Vector3.zero;

    void INavigationHandler.OnNavigationStarted(NavigationEventData eventData)
    {
        InputManager.Instance.PushModalInputHandler(gameObject);
    }

    void INavigationHandler.OnNavigationUpdated(NavigationEventData eventData)
    {
        if (isNavigationEnabled)
        {
            /* TODO: DEVELOPER CODING EXERCISE 2.c */

            // 2.c: Calculate a float rotationFactor based on eventData's NormalizedOffset.x multiplied by RotationSensitivity.
            // This will help control the amount of rotation.
            float rotationFactor = eventData.NormalizedOffset.x * RotationSensitivity;

            // 2.c: transform.Rotate around the Y axis using rotationFactor.
            transform.Rotate(new Vector3(0, -1 * rotationFactor, 0));
        }
    }

    void INavigationHandler.OnNavigationCompleted(NavigationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void INavigationHandler.OnNavigationCanceled(NavigationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void IManipulationHandler.OnManipulationStarted(ManipulationEventData eventData)
    {
        if (!isNavigationEnabled)
        {
            InputManager.Instance.PushModalInputHandler(gameObject);

            manipulationOriginalPosition = transform.position;
        }
    }

    void IManipulationHandler.OnManipulationUpdated(ManipulationEventData eventData)
    {
        if (!isNavigationEnabled)
        {
            /* TODO: DEVELOPER CODING EXERCISE 4.a */

            // 4.a: Make this transform's position be the manipulationOriginalPosition + eventData.CumulativeDelta
            transform.position = manipulationOriginalPosition + eventData.CumulativeDelta;
        }
    }

    void IManipulationHandler.OnManipulationCompleted(ManipulationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void IManipulationHandler.OnManipulationCanceled(ManipulationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void ISpeechHandler.OnSpeechKeywordRecognized(SpeechEventData eventData)
    {
        if (eventData.RecognizedText.Equals("Move Astronaut"))
        {
            isNavigationEnabled = false;
        }
        else if (eventData.RecognizedText.Equals("Rotate Astronaut"))
        {
            isNavigationEnabled = true;
        }
        else
        {
            return;
        }

        eventData.Use();
    }
}

Построение и Развертывание

  • Перестройте в Unity, а затем выполните сборку и развертывание из Visual Studio, чтобы запустить приложение в HoloLens.
  • Переместите руку перед HoloLens и поднимите указательный палец, чтобы его можно было отслеживать.
  • Наведите указатель мыши на астронавта.
  • Скажите "Переместить астронавта", чтобы переместить астронавта с помощью жеста манипуляции.
  • Четыре стрелки должны отображаться вокруг курсора, чтобы указать, что программа теперь будет реагировать на события манипуляции.
  • Опустите указательный палец вниз к большому пальцу и держите их щипнуть вместе.
  • Когда вы перемещаете руку вокруг, астронавт будет двигаться тоже (это манипуляция).
  • Поднимите указательный палец, чтобы остановить манипулирование астронавтом.
  • Примечание. Если вы не говорите "Переместить астронавта" перед перемещением руки, вместо этого будет использоваться жест навигации.
  • Скажите "Повернуть астронавта", чтобы вернуться в вращаемое состояние.

Глава 5. Расширение модели

Задачи

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

Instructions

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

  1. Добавьте новое ключевое слово "Expand Model" (Развернуть модель), чтобы развернуть модель астронавтов.
  2. Добавьте новое ключевое слово "Reset Model", чтобы вернуть модель в исходную форму.

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

  1. Нажмите кнопку " АстронавтManager " в инспекторе и разверните раздел "Ключевые слова " в инспекторе.
  2. + Щелкните справа, чтобы добавить новое ключевое слово.
  3. Введите ключевое слово в качестве модели развертывания. При необходимости вы можете добавить сочетание клавиш.
  4. + Щелкните справа, чтобы добавить новое ключевое слово.
  5. Введите ключевое слово в качестве модели сброса. При необходимости вы можете добавить сочетание клавиш.
  6. На панели инспектора нажмите кнопку "Добавить компонент ".
  7. В меню введите обработчик ввода речи в поле поиска. Выберите результат поиска.
  8. Проверьте , является ли глобальный прослушиватель, так как мы хотим, чтобы эти команды работали независимо от gameObject, который мы фокусируем.
  9. Нажмите кнопку + и выберите "Развернуть модель " в раскрывающемся списке ключевых слов.
  10. + Щелкните поле "Ответ" и перетащите АстронавтManager из иерархии в поле None (Object).
  11. Теперь щелкните раскрывающийся список "Нет функции ", выберите AstronautManager, а затем ExpandModelCommand.
  12. Нажмите кнопку обработчика + голосового ввода и выберите "Сбросить модель" в раскрывающемся списке ключевых слов.
  13. + Щелкните поле "Ответ" и перетащите АстронавтManager из иерархии в поле None (Object).
  14. Теперь щелкните раскрывающийся список "Нет функции ", выберите AstronautManager, а затем ResetModelCommand.

How to set-up the Speech Input Source and Handler for chapter 5

Построение и Развертывание

  • Тестирование Выполните сборку и развертывание приложения в HoloLens.
  • Скажите "Развернуть модель ", чтобы увидеть развернутую модель астронавтов.
  • Используйте навигацию для поворота отдельных частей костюма астронавта.
  • Предположим, перемещение астронавта, а затем использовать манипуляции для перемещения отдельных частей костюма астронавта.
  • Скажите поворот астронавта , чтобы повернуть куски снова.
  • Скажите "Сбросить модель", чтобы вернуть астронавта в исходную форму.

Конец

Поздравляем! Теперь вы завершили ввод MR 211: жест.

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