Поделиться через


Выбор целевого объекта с поддержкой глаз — MRTK2

MRTK

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

  • Просмотр & скажите "Выбрать" (голосовая команда по умолчанию)
  • Посмотрите, & скажите "Explode" или "Pop" (пользовательские голосовые команды)
  • Поиск & кнопки Bluetooth
  • Посмотрите & Щепотка (т. е. подождите руку перед собой и сведите большой и указательный пальцы вместе)

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

1. Используйте основной указатель фокуса:

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

Пример:

Пользователь хочет выбрать удаленную голографическую кнопку. Как разработчик вы хотите предоставить гибкое решение, которое позволит пользователю выполнять эти задачи в различных условиях:

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

Важно!

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

2. Используйте фокус глаза и лучи рук одновременно:

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

Например: в приложении пользователь может использовать дальние лучи для управления голографической механической установкой, например, захватить и удерживать некоторые удаленные части голографического двигателя и удерживать их на месте. При этом пользователь должен выполнить ряд инструкций и записать свой прогресс, пометив некоторые проверка коробки. Если руки пользователя не заняты, было бы инстинктивно коснуться проверка прямоугольник или выбрать его с помощью луча руки. Однако если у пользователя заняты руки, как в нашем случае с некоторыми голографическими частями двигателя, вы хотите, чтобы пользователь мог легко прокручивать инструкции с помощью взгляда и просто посмотреть на проверка поле и сказать "проверка его!".

Для этого необходимо использовать скрипт EyeTrackingTarget, который не зависит от основной платформы MRTK FocusHandlers и будет рассмотрен ниже.

1. Использование универсальных обработчиков фокуса и указателей

Если отслеживание взгляда настроено правильно (см. раздел Базовая настройка MRTK для использования отслеживания взгляда), пользователи могут выбирать голограммы с помощью глаз так же, как и для любого другого ввода фокуса (например, взгляд головы или луч руки). Это обеспечивает большое преимущество гибкого взаимодействия с голограммами, определяя тип фокуса main в профиле указателя ввода MRTK в зависимости от потребностей пользователя, оставляя код нетронутым. Это позволяет переключаться между взглядами головы или глаза без изменения строки кода или замены лучей рук на нацеливание глаз для дальних взаимодействий.

Фокусировка на голограмме

Для обнаружения фокусировки голограммы используйте интерфейс IMixedRealityFocusHandler , который предоставляет два элемента интерфейса: OnFocusEnter и OnFocusExit.

Ниже приведен простой пример из файла ColorTap.cs для изменения цвета голограммы при просмотре.

public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler
{
    void IMixedRealityFocusHandler.OnFocusEnter(FocusEventData eventData)
    {
        material.color = color_OnHover;
    }

    void IMixedRealityFocusHandler.OnFocusExit(FocusEventData eventData)
    {
        material.color = color_IdleState;
    }
    ...
}

Выбор голограммы с фокусом

Чтобы выбрать голограмму с фокусом, используйте PointerHandler для прослушивания входных событий для подтверждения выделения. Например, добавление IMixedRealityPointerHandler приведет к реакции на простые входные данные указателя. Интерфейс IMixedRealityPointerHandler требует реализации следующих трех членов интерфейса: OnPointerUp, OnPointerDown и OnPointerClicked.

В приведенном ниже примере мы изменим цвет голограммы, посмотрев на нее и зажимая или произнеся "выбрать". Требуемое действие для активации события определяется eventData.MixedRealityInputAction == selectAction тем, что мы можем задать тип selectAction в редакторе Unity . По умолчанию это действие "Выбрать". Типы доступных Объектов MixedRealityInputActions можно настроить в профиле MRTK с помощью параметра Профиль конфигурации MRTK ->Входные -Входные> действия.

public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler, IMixedRealityPointerHandler
{
    // Allow for editing the type of select action in the Unity Editor.
    [SerializeField]
    private MixedRealityInputAction selectAction = MixedRealityInputAction.None;
    ...

    void IMixedRealityPointerHandler.OnPointerUp(MixedRealityPointerEventData eventData)
    {
        if (eventData.MixedRealityInputAction == selectAction)
        {
            material.color = color_OnHover;
        }
    }

    void IMixedRealityPointerHandler.OnPointerDown(MixedRealityPointerEventData eventData)
    {
        if (eventData.MixedRealityInputAction == selectAction)
        {
            material.color = color_OnSelect;
        }
    }

    void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData) { }
}

Специфичный для взгляда BaseEyeFocusHandler

Учитывая, что взгляд может сильно отличаться от других входных данных указателя, вы можете реагировать на ввод фокуса только в том случае, если это взгляд и в настоящее время это основной указатель ввода. Для этой цели следует использовать BaseEyeFocusHandler , который является специфическим для отслеживания взгляда и является производным от BaseFocusHandler. Как упоминалось ранее, он активируется только в том случае, если нацеливание взгляда в настоящее время является основным вводом указателя (т. е. луч руки не активен). Дополнительные сведения см. в разделе Поддержка жестов взгляда и рук.

Ниже приведен пример из EyeTrackingDemo-03-Navigation (Assets/MRTK/Examples/Demos/EyeTracking/Scenes). В этой демонстрации есть две трехмерные голограммы, которые будут поворачиваться в зависимости от того, какая часть объекта просматривается: если пользователь смотрит на левую сторону голограммы, то эта часть будет медленно двигаться к передней части, обращенной к пользователю. Если смотреть на правую сторону, то эта часть будет медленно двигаться вперед. Это поведение, которое может не потребоваться всегда, а также что-то, что вы не хотите случайно активироваться лучом руки или взглядом головы. При присоединении OnLookAtRotateByEyeGaze GameObject будет поворачиваться при просмотре.

public class OnLookAtRotateByEyeGaze : BaseEyeFocusHandler
{
    ...

    protected override void OnEyeFocusStay()
    {
        // Update target rotation
        RotateHitTarget();
    }

    ...

    ///
    /// This function computes the rotation of the target to move the currently
    /// looked at aspect slowly to the front.
    ///
    private void RotateHitTarget()
    {
        // Example for querying the hit position of the eye gaze ray using EyeGazeProvider
        Vector3 TargetToHit = (this.gameObject.transform.position - InputSystem.EyeGazeProvider.HitPosition).normalized;

        ...
    }
}

Полный список доступных событий см. в BaseEyeFocusHandlerдокументации по API :

  • OnEyeFocusStart: Активируется, когда луч взгляда начинает пересекаться с коллайдером этой цели.
  • OnEyeFocusStay: Активируется , когда луч взгляда пересекается с коллайдером этой цели.
  • OnEyeFocusStop: Активируется после того, как луч взгляда перестает пересекаться с коллайдером этой цели.
  • OnEyeFocusDwell: Активируется после того, как луч взгляда пересекается с коллайдером этого целевого объекта в течение указанного периода времени.

2. Независимая специфичная для взгляда eyeTrackingTarget

Наконец, мы предоставляем решение, позволяющее обрабатывать входные данные на основе глаз, полностью независимые от других указателей фокуса с помощью скрипта EyeTrackingTarget .

Это имеет три преимущества:

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

Есть и некоторые недостатки:

  • Дополнительные усилия по обработке отдельных входных данных по отдельности.
  • Нет элегантной деградации: он поддерживает только нацеливание на глаза. Если отслеживание взгляда не работает, вам потребуется дополнительный резервный вариант.

Как и BaseFocusHandler, EyeTrackingTarget поставляется с несколькими событиями Unity, которые можно прослушивать с помощью редактора Unity (см. пример ниже) или с помощью AddListener() в коде:

  • OnLookAtStart()
  • WhileLookingAtTarget()
  • OnLookAway()
  • OnDwell()
  • OnSelected()

Ниже мы рассмотрим несколько примеров использования EyeTrackingTarget.

Пример 1. Смарт-уведомления, поддерживаемые глазами

В EyeTrackingDemo-02-TargetSelection разделе (Assets/MRTK/Examples/Demos/EyeTracking/Scenes) можно найти пример "умных внимательных уведомлений" , которые реагируют на ваш взгляд. Это трехмерные текстовые поля, которые можно поместить в сцену и которые будут плавно увеличиваться и поворачиваться к пользователю при просмотре, чтобы облегчить читаемость. Пока пользователь читает уведомление, информация по-прежнему отображается четко и четко. После прочтения и отвлекаясь от уведомления, уведомление будет автоматически отклонено и исчезнет. Для этого есть несколько универсальных сценариев поведения, которые не относятся к отслеживанию взгляда, например:

Преимущество этого подхода заключается в том, что одни и те же скрипты могут повторно использоваться различными событиями. Например, голограмма может начать работать с пользователем на основе голосовых команд или после нажатия виртуальной кнопки. Чтобы активировать эти события, можно просто сослаться на методы, которые должны выполняться в скрипте EyeTrackingTarget , присоединенном к GameObject.

В примере "интеллектуальных внимательных уведомлений" происходит следующее:

  • OnLookAtStart(): уведомление начинается...

    • FaceUser.Engage: ... обратиться к пользователю.
    • ChangeSize.Engage: ... увеличение размера (до указанного максимального масштаба).
    • BlendOut.Engage: ... начинает смешиваться в большем (после того, как в более тонком состоянии простоя) начинает смешиваться.
  • OnDwell(): сообщает скрипту BlendOut о том, что уведомление было просмотрено достаточно.

  • OnLookAway(): уведомление начинается...

    • FaceUser.Disengage: ... Вернитесь к исходной ориентации.
    • ChangeSize.Disengage: ... уменьшить до исходного размера.
    • BlendOut.Disengage: ... начинает смешиваться. Если onDwell() был активирован, полностью смешайте и уничтожите, в противном случае вернитесь в состояние простоя.

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

Целевое уведомление

Пример 2. Голографический драгоценный камень медленно вращается при взгляде на него

Как и в примере 1, мы можем легко создать обратную связь для голографических драгоценных камней в EyeTrackingDemo-02-TargetSelection сцене (Assets/MRTK/Examples/Demos/EyeTracking/Scenes), которая будет медленно вращаться в постоянном направлении и с постоянной скоростью (в отличие от приведенного выше примера поворота) при просмотре. Все, что вам нужно, — активировать вращение голографического камня из события WhileLookingAtTarget()EyeTrackingTarget(). Ниже приведены некоторые дополнительные сведения:

  1. Создайте универсальный скрипт, включающий общедоступную функцию для смены GameObject, к которому он присоединен. Ниже приведен пример из файла RotateWithConstSpeedDir.cs , где можно настроить направление и скорость поворота из редактора Unity.

    using UnityEngine;
    
    namespace Microsoft.MixedReality.Toolkit.Examples.Demos.EyeTracking
    {
        /// <summary>
        /// The associated GameObject will rotate when RotateTarget() is called based on a given direction and speed.
        /// </summary>
        public class RotateWithConstSpeedDir : MonoBehaviour
        {
            [Tooltip("Euler angles by which the object should be rotated by.")]
            [SerializeField]
            private Vector3 RotateByEulerAngles = Vector3.zero;
    
            [Tooltip("Rotation speed factor.")]
            [SerializeField]
            private float speed = 1f;
    
            /// <summary>
            /// Rotate game object based on specified rotation speed and Euler angles.
            /// </summary>
            public void RotateTarget()
            {
                transform.eulerAngles = transform.eulerAngles + RotateByEulerAngles * speed;
            }
        }
    }
    
  2. Добавьте скрипт в EyeTrackingTarget целевой GameObject и составьте ссылку на функцию RotateTarget() в триггере UnityEvent, как показано на снимке экрана ниже:

    Пример EyeTrackingTarget

Пример 3. Выбор целевого объекта с поддержкой многомодального взгляда

В предыдущем примере мы показали, насколько легко определить, просматривается ли целевой объект, и как вызвать реакцию на это. Далее давайте запустим драгоценные камни с помощью события OnSelected() из EyeTrackingTarget. Интересно, как запускается выбор. позволяет EyeTrackingTarget быстро назначать различные способы вызова выделения:

  • Жест сжатия. При установке для параметра "Действие выбора" значения "Выбрать" используется жест руки по умолчанию для активации выделения. Это означает, что пользователь может просто поднять руку и сжать большой и указательный пальцы вместе, чтобы подтвердить выбор.

  • Скажите "Выбрать": используйте голосовую команду по умолчанию "Выбрать" для выбора голограммы.

  • Произнесите "Explode" или "Pop". Чтобы использовать пользовательские голосовые команды, необходимо выполнить два шага:

    1. Настройка настраиваемого действия, например DestroyTarget

      • Перейдите к MRTK —> Входные данные —> Действия ввода
      • Нажмите кнопку "Добавить новое действие"
    2. Настройка голосовых команд, запускающих это действие, таких как "Взрыв" или "Pop"

      • Перейдите к MRTK —> ввод —> речь
      • Нажмите кнопку "Добавить новую голосовую команду"
        • Связывание только что созданного действия
        • Назначьте ключевой код , чтобы разрешить активацию действия с помощью нажатия кнопки

Пример голосовых команд EyeTrackingTarget

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

  • В редакторе Unity: Можно просто связать скрипт, прикрепленный к каждому из наших шаблонов gem, с событием OnSelected() Unity в редакторе Unity.
  • В коде: Если вы не хотите перетаскивать GameObjects, вы также можете просто добавить прослушиватель событий непосредственно в сценарий.
    Ниже приведен пример того, как мы сделали это в скрипте HitBehaviorDestroyOnSelect :
/// <summary>
/// Destroys the game object when selected and optionally plays a sound or animation when destroyed.
/// </summary>
[RequireComponent(typeof(EyeTrackingTarget))] // This helps to ensure that the EyeTrackingTarget is attached
public class HitBehaviorDestroyOnSelect : MonoBehaviour
{
    ...
    private EyeTrackingTarget myEyeTrackingTarget = null;

    private void Start()
    {
        myEyeTrackingTarget = this.GetComponent<EyeTrackingTarget>();

        if (myEyeTrackingTarget != null)
        {
            myEyeTrackingTarget.OnSelected.AddListener(TargetSelected);
        }
    }

    ...

    ///
    /// This is called once the EyeTrackingTarget detected a selection.
    ///
    public void TargetSelected()
    {
        // Play some animation
        // Play some audio effect
        // Handle destroying the target appropriately
    }
}

Пример 4. Совместное использование лучей рук и взгляда

Лучи рук берут приоритет над головой и взглядом нацеливания. Это означает, что если лучи рук включены, то в тот момент, когда руки появятся в поле зрения, луч будет выступать в качестве основного указателя. Однако могут возникнуть ситуации, когда вы хотите использовать лучи рук, по-прежнему обнаруживая, смотрит ли пользователь на определенную голограмму. Легко! По сути, требуется два шага:

1. Включить луч руки. Чтобы включить луч руки, перейдите к Смешанная реальность Набор средств —> Ввод —> Указатели. В EyeTrackingDemo-00-RootScene, где Смешанная реальность Toolkit настраивается один раз для всех демонстрационных сцен отслеживания взгляда, вы должны увидеть EyeTrackingDemoPointerProfile. Вы можете создать новый профиль ввода с нуля или адаптировать текущий профиль отслеживания взгляда:

  • С нуля: На вкладке Указатели выберите DefaultMixedRealityInputPointerProfile в контекстном меню. Это профиль указателя по умолчанию, для которого уже включен луч руки! Чтобы изменить курсор по умолчанию (непрозрачную белую точку), просто клонируйте профиль и создайте собственный пользовательский профиль указателя. Затем замените DefaultCursorна EyeGazeCursor в разделе Заготовка курсора взгляда.
  • На основе существующего EyeTrackingDemoPointerProfile дважды щелкните eyeTrackingDemoPointerProfile и добавьте следующую запись в поле Параметры указателя:
    • Тип контроллера: "Сформулированная рука", "Windows Mixed Reality"
    • Handedness: Любой
    • Заготовка указателя: DefaultControllerPointer

2. Обнаружение того, что голограмма просматривается: используйте EyeTrackingTarget скрипт, чтобы включить обнаружение просмотра голограммы, как описано выше. Вы также можете взглянуть на FollowEyeGaze пример сценария для вдохновения, так как на этом изображена голограмма, следя за взглядом (например, курсором), независимо от того, включены ли лучи рук.

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


Вернуться к "Отслеживание взгляда в MixedRealityToolkit"