Указатели

Указатель

В этой статье объясняется, как настроить и реагировать на ввод указателя на практике по сравнению с архитектурой указателя .

Экземпляры указателей устанавливаются автоматически во время выполнения при обнаружении нового контроллера. К контроллеру можно подключить более одного указателя. например, при использовании профиля указателя по умолчанию Windows Mixed Reality контроллеры получают как линию, так и указатель параболическим для нормального выбора и телетранспорта соответственно.

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

Указатели настраиваются как часть входной системы в МРТК через MixedRealityPointerProfile . Этот тип профиля назначается MixedRealityInputSystemProfile в инспекторе конфигурации мртк. Профиль указателя определяет курсор, типы указателей, доступные во время выполнения, и то, как эти указатели обмениваются данными друг с другом, чтобы решить, какая из них активна.

  • Указывающее экстент — определяет максимальное расстояние, для которого указатель может взаимодействовать с GameObject.

  • Указание Райкаст слоя-масок — это упорядоченный массив лайермаскс, позволяющий определить, какие возможные объекты gameobject могут взаимодействовать с любым заданным указателем, а также порядок попыток взаимодействия. Это может быть полезно для обеспечения взаимодействия указателей с элементами пользовательского интерфейса перед другими объектами сцены. Пример профиля указателя

Настройка параметров указателя

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

Пример профиля параметров указателя

Каждая запись указателя определяется следующим набором данных:

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

    • Например, покепоинтер отвечает за объекты "Знакомство" с помощью пальца. по умолчанию он помечен как поддерживающий только тип контроллера с установленным именем. Экземпляры указателей создаются только в том случае, если контроллер станет доступным, а в частности тип контроллера определяет, с какими контроллерами может быть создан этот указатель prefab.
  • Правой или левой — позволяет создать указатель на экземпляр только для конкретной руки (слева направо).

Примечание

Если задать для свойства правой или левой записи указателя значение None , это позволит эффективно отключить его от системы в качестве альтернативы удалению этого указателя из списка.

  • Pointer prefab — этот ресурс prefab будет создан при отслеживании контроллера, соответствующего указанному типу контроллера и правой или левой.

С контроллером можно связать несколько указателей. Например, в DefaultHoloLens2InputSystemProfile (Assets/мртк/SDK/Profiles/HoloLens2/) контроллер с управляемым кодом связан с DefaultHoloLens2InputSystemProfile, грабпоинтери дефаултконтроллерпоинтер (то есть луча).

Примечание

МРТК предоставляет набор Prefabs указателя в Assets/мртк/SDK/Features/UX/Prefabs/указатели. Новый пользовательский prefab можно построить, если он содержит один из сценариев указателя в Assets/мртк/SDK/Features/UX/Scripts /Pointers или любом другом скрипте, реализующем .

Настройка курсора

Курсор взгляда можно настроить непосредственно через GazeCursorPrefab свойство в в MixedRealityInputSystemProfile редакторе. Чтобы настроить курсор, используемый для других указателей, необходимо изменить prefab, используемый в CursorPrefab поле соответствующего объекта BaseControllerPointer . Чтобы изменить курсор программно, измените BaseCursor свойство в соответствующем IMixedRealityPointer поведении.

Свойство prefab курсора

Примеры реализации поведения курсоров см. в нашем prefabsе в разделе Assets/мртк/SDK/Features/UX/Prefabs/Cursors . В частности, дефаултгазекурсор предоставляет надежную реализацию изменения изображения курсора на основе контекстного состояния.

Классы указателей по умолчанию

Следующие классы — это стандартные указатели МРТК, доступные и определенные в профиле указателя мртк по умолчанию, описанном выше. Каждый prefab указателя, указанный в разделе Assets/мртк/SDK/Features/UX/Prefabs/ Pointers, содержит один из прикрепленных компонентов указателя.

МРТК указатели по умолчанию

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

LinePointer

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

для контроллеров движения, таких как в окулус, naopak и Windows Mixed Reality, поворот будет соответствовать повороту контроллера. для других контроллеров, таких как HoloLens 2 накладываемые руки, поворот соответствует предоставленной системой, указывающей на свою руку.

МРТК, строка указателя
CurvePointer

Курвепоинтер расширяет класс линепоинтер , позволяя выполнять многошаговые приведения вдоль кривой. Базовый класс указателя полезен для таких искривленных экземпляров, как указатели на перемещение, когда линия постоянно изогнута в парабола.

ShellHandRayPointer

Реализация шеллхандрайпоинтер, которая расширяется из , используется в качестве значения по умолчанию для профиля указателя мртк. Дефаултконтроллерпоинтер prefab реализует класс.

GGVPointer

кроме того, он называется указателем « взгляд/жест/Voice» (ггв) , ггвпоинтер выключает HoloLens вид и касание в стиле 1, в первую очередь с помощью сенсорного экрана и касания, а также сенсорного выбора. Позиции и направления указателя ГГВ определяются положением и поворотом головного элемента.

TouchPointer

Таучпоинтер отвечает за работу с сенсорным входом Unity (т. е. сенсорного экрана). Это «дальнее взаимодействие», так как касание экрана приводит к преобразованию луча из камеры в потенциально далекое место в сцене.

MousePointer

MousePointer выводит экран в мир райкаст для дальнего взаимодействия, но для мыши вместо касания.

Указатель мыши

Примечание

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

Близкие указатели

PokePointer

Покепоинтер используется для взаимодействия с игровыми объектами, которые поддерживают "приближается к сенсорному взаимодействию". которые являются объекты gameobject, которые имеют присоединенный NearInteractionTouchable скрипт. В случае с Унитюи этот указатель выполняет поиск Неаринтерактионтаучаблеунитюис. Покепоинтер использует Сферекаст для определения ближайшего сенсорного элемента и используется для управления такими элементами, как нажатые кнопки.

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

Полезные свойства указателя для последующих действий:

  • Таучабледистанце: максимальное расстояние, в котором можно взаимодействовать с сенсорной поверхностью
  • Визуальные элементы: объект Game, используемый для визуализации визуального кончика пальца (по умолчанию кольцо на пальце).
  • Line: необязательная линия для отображения активной поверхности ввода.
  • Вставка масок слоев — упорядоченный массив лайермаскс для определения возможных объекты gameobject, с которыми может взаимодействовать указатель, а также порядок попыток взаимодействия. Обратите внимание, что GameObject также должен иметь NearInteractionTouchable компонент для взаимодействия с указателем на Вставка.
Вставка указателя
SpherePointer

Сферепоинтер использует UnityEngine. физик. оверлапсфере для указания ближайшего объекта для взаимодействия, что полезно для «захвата» входных данных, таких как . Как и PokePointer/NearInteractionTouchable функциональная пара, для взаимодействия с указателем сферы, объект игры должен содержать компонент, который является NearInteractionGrabbable сценарием.

Захватить указатель

Свойства указателя на полезные сферы:

  • Радиус приведения сферы: Радиус сферы, используемый для запроса объектов, которые могут быть извлечены.
  • Приближается к полю объекта: расстояние на вершине радиуса приведения сферы к запросу для определения, находится ли объект рядом с указателем. Всего для обнаружения близких объектов RADIUS — это поле радиуса приведение типа сферы
  • Угол Ближнего сектора объекта: угол вокруг прямой оси указателя для запроса ближайших объектов. Делает IsNearObject функцию запроса, подобную конусной. По умолчанию задано значение 66 градусов, совпадающее с поведением Hololens 2

Указатель сферы изменен на запрос только объектов в прямом направлении

  • Фактор сглаживания близких объектов: Коэффициент сглаживания для обнаружения близкого объекта. Если объект обнаружен в радиусе вблизи объекта, запрашиваемый радиус становится ближайшим объектом RADIUS * (1 + Коэффициент сглаживания близких объектов) для уменьшения чувствительности и усложняет объект для выхода из диапазона обнаружения.
  • Маски слоя захвата — приоритетный массив лайермаскс для определения возможных объекты gameobject, с которыми может взаимодействовать указатель, а также порядок попыток взаимодействия. Обратите внимание, что GameObject должен также иметь NearInteractionGrabbable для взаимодействия с сферепоинтер.

    Примечание

    Уровень пространственной осведомленности отключен в Грабпоинтер prefab по умолчанию, предоставленном МРТК. Это делается для уменьшения влияния запроса на перекрытие сфер с пространственной сеткой. Это можно сделать, изменив prefab Грабпоинтер.

  • Игнорировать конфликты, отсутствующие в фов , — следует ли игнорировать конфликты, которые могут находиться ближе к указателю, но не в самом деле в Visual фов. Это может препятствовать случайному захвату и позволит включить отправку при приближении к захватау, но не может его увидеть. Визуальный фов определяется с помощью конуса вместо типичного фрустум по соображениям производительности. Этот конус выравнивается по центру и ориентирован так же, как и фрустум камеры с радиусом, равным половине отображаемой высоты (или вертикальной фов).
Указатель сферы

Указатели телепортируйтесь

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

Поддержка указателей для платформ смешанной реальности

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

Указатель OpenVR: Windows Mixed Reality HoloLens 1 HoloLens 2
шеллхандрайпоинтер Допустимо Допустимо Допустимо
телепортпоинтер Допустимо Допустимо
ггвпоинтер Допустимо
сферепоинтер Допустимо
покепоинтер Допустимо

Взаимодействие указателей через код

Интерфейсы событий указателя

Одностраничные, реализующие один или несколько из следующих интерфейсов и назначенные GameObject с помощью, получат Collider события взаимодействия указателя в соответствии с определением связанного интерфейса.

Событие Описание Обработчик
До изменения фокуса или изменения фокуса Порождается как в игровом объекте, так и при каждом изменении фокуса. IMixedRealityFocusChangedHandler
Фокус на ввод/выход Порождается на игровом объекте, чтобы получить фокус при нажатии первого указателя мыши и при потере фокуса, когда последний указатель покидает его. IMixedRealityFocusHandler
Указатель "вниз"/"перемещено/вверх" Вызывается для нажатия указателя на отчет, перетаскивания и освобождения. IMixedRealityPointerHandler
Касание запущено, Обновлено/завершено Порождается указателями, поддерживающими касание, например, PokePointer для создания отчетов. IMixedRealityTouchHandler

Примечание

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

События ввода указателя в действии

Входные события указателя распознаются и обрабатываются системой ввода МРТК так же, как обычные события ввода. Разница заключается в том, что события ввода указателя обрабатываются только GameObject в фокусе указателем, который активировал событие ввода, а также любыми глобальными обработчиками ввода. Обычные события ввода обрабатываются объекты gameobject в фокусе для всех активных указателей.

  1. Входная система МРТК распознает событие ввода.
  2. Входная система МРТК запускает соответствующую функцию интерфейса для входного события во все зарегистрированные глобальные обработчики ввода.
  3. Входная система определяет, в какой GameObject фокус находится указатель, который активировал событие.
    1. Входная система использует систему событий Unity для запуска соответствующей функции интерфейса для всех совпадающих компонентов в фокусе GameObject
    2. Если в любой момент входное событие было помечено как используемое, процесс завершится, а последующие объекты gameobject не получат обратные вызовы.
      • Пример: компоненты, реализующие интерфейс, IMixedRealityFocusHandler будут искать GameObject или теряет фокус
      • Примечание. Система событий Unity будет выполнять поиск в родительском GameObject, если ни один из компонентов, соответствующих требуемому интерфейсу, не найден в текущем GameObject.
  4. Если не зарегистрированы глобальные входные обработчики и не найден GameObject с соответствующим компонентом или интерфейсом, то входная система будет вызывать каждый из зарегистрированных входных обработчиков.

Пример

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

public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler, IMixedRealityPointerHandler
{
    private Color color_IdleState = Color.cyan;
    private Color color_OnHover = Color.white;
    private Color color_OnSelect = Color.blue;
    private Material material;

    private void Awake()
    {
        material = GetComponent<Renderer>().material;
    }

    void IMixedRealityFocusHandler.OnFocusEnter(FocusEventData eventData)
    {
        material.color = color_OnHover;
    }

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

    void IMixedRealityPointerHandler.OnPointerDown(
         MixedRealityPointerEventData eventData) { }

    void IMixedRealityPointerHandler.OnPointerDragged(
         MixedRealityPointerEventData eventData) { }

    void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
    {
        material.color = color_OnSelect;
    }
}

Указатели запросов

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

var pointers = new HashSet<IMixedRealityPointer>();

// Find all valid pointers
foreach (var inputSource in CoreServices.InputSystem.DetectedInputSources)
{
    foreach (var pointer in inputSource.Pointers)
    {
        if (pointer.IsInteractionEnabled && !pointers.Contains(pointer))
        {
            pointers.Add(pointer);
        }
    }
}

Основной указатель

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

private void OnEnable()
{
    var focusProvider = CoreServices.InputSystem?.FocusProvider;
    focusProvider?.SubscribeToPrimaryPointerChanged(OnPrimaryPointerChanged, true);
}

private void OnPrimaryPointerChanged(IMixedRealityPointer oldPointer, IMixedRealityPointer newPointer)
{
    ...
}

private void OnDisable()
{
    var focusProvider = CoreServices.InputSystem?.FocusProvider;
    focusProvider?.UnsubscribeFromPrimaryPointerChanged(OnPrimaryPointerChanged);

    // This flushes out the current primary pointer
    OnPrimaryPointerChanged(null, null);
}

PrimaryPointerExampleСцена (Assets/мртк/examples/демонстрация/вход/сцена/примарипоинтер) показывает, как использовать PrimaryPointerChangedHandler события for для реагирования на новый первичный указатель.

Пример основного указателя

Результат указателя

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

private void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
{
    var result = eventData.Pointer.Result;
    var spawnPosition = result.Details.Point;
    var spawnRotation = Quaternion.LookRotation(result.Details.Normal);
    Instantiate(MyPrefab, spawnPosition, spawnRotation);
}

В PointerResultExample сцене (Assets/мртк/examples/демонстрация/input/сцены/поинтерресулт/поинтерресултексампле. Unity) показано, как использовать указатель Result для порождения объекта в месте попадания.

Результат указателя

Отключить указатели

Чтобы включить и отключить указатели (например, для отключения руки), задайте PointerBehavior для данного типа указателя через PointerUtils .

// Disable the hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);

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

// Disable the gaze pointer
PointerUtils.SetGazePointerBehavior(PointerBehavior.AlwaysOff);

// Set the behavior to match HoloLens 1
// Note, if on HoloLens 2, you must configure your pointer profile to make the GGV pointer show up for articulated hands.
public void SetHoloLens1()
{
    PointerUtils.SetPokePointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetGrabPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetGGVBehavior(PointerBehavior.Default);
}

PointerUtilsTurnPointersOnOff Дополнительные примеры см. в разделе и.

Взаимодействие указателей через редактор

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

Обработчик указателя

Область указателя

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

Это можно изменить, обновив DefaultControllerPointerShellHandRayPointer поля компонента Prefab:

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

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

См. также