Добавление близкого взаимодействия — MRTK2
Близкие взаимодействия приходят в виде касаний и захватов. События касания и захвата вызываются как события указателя pokePointer и SpherePointer соответственно.
Для прослушивания событий сенсорного ввода и (или) захвата в определенном GameObject требуется три ключевых шага.
- Убедитесь, что соответствующий указатель зарегистрирован в профиле конфигурации MAIN MRTK.
- Убедитесь, что нужный GameObject имеет соответствующий компонент сценария захвата или сенсорного ввода и
Unity Collider
. - Реализуйте интерфейс обработчика входных данных в присоединенном скрипте к нужному объекту GameObject для прослушивания событий захвата или сенсорного ввода .
Добавление взаимодействий захвата
Убедитесь, что SpherePointer зарегистрирован в профиле указателя MRTK.
Профиль MRTK по умолчанию и профиль HoloLens 2 по умолчанию уже содержат SpherePointer. Чтобы убедиться, что SpherePointer будет создан, выберите профиль конфигурации MRTK и перейдите в разделПараметры указателявходных>указателей>. Заготовка по умолчанию
GrabPointer
(Assets/MRTK/SDK/Features/UX/Prefabs/Pointers) должна быть указана с типом контроллераШарообразная рука. Пользовательская заготовкаSpherePointer
может использоваться до тех пор, пока она реализует класс .По умолчанию указатель захвата запрашивает близлежащие объекты в конусе вокруг точки захвата в соответствии с интерфейсом HoloLens 2 по умолчанию.
В GameObject, который должен быть захватываемым, добавьте
NearInteractionGrabbable
, а также коллайдер.Убедитесь, что слой GameObject находится на захватываемом слое. По умолчанию захватываются все слои, кроме пространственной осведомленности и пропускания лучей . Чтобы узнать, какие слои можно захватывать, проверьте маски слоя захвата в заготовкеGrabPointer .
В GameObject или одном из его предков добавьте компонент скрипта, реализующий
IMixedRealityPointerHandler
интерфейс . Любой предок объекта с параметромNearInteractionGrabbable
также сможет получать события указателя.
Пример кода захвата
Ниже приведен скрипт, который будет выводить, если событие является касанием или захватом. В соответствующей функции интерфейса IMixedRealityPointerHandler можно просмотреть тип указателя, который активирует это событие через MixedRealityPointerEventData
. Если указателем является SpherePointer, взаимодействие является захватом.
public class PrintPointerEvents : MonoBehaviour, IMixedRealityPointerHandler
{
public void OnPointerDown(MixedRealityPointerEventData eventData)
{
if (eventData.Pointer is SpherePointer)
{
Debug.Log($"Grab start from {eventData.Pointer.PointerName}");
}
if (eventData.Pointer is PokePointer)
{
Debug.Log($"Touch start from {eventData.Pointer.PointerName}");
}
}
public void OnPointerClicked(MixedRealityPointerEventData eventData) {}
public void OnPointerDragged(MixedRealityPointerEventData eventData) {}
public void OnPointerUp(MixedRealityPointerEventData eventData) {}
}
Добавление сенсорных взаимодействий
Процесс добавления сенсорных взаимодействий в элементах UnityUI отличается от процесса для ванили 3D GameObjects. Вы можете перейти к следующему разделу Пользовательский интерфейс Unity, чтобы включить компоненты пользовательского интерфейса Unity.
Однако для обоих типов элементов пользовательского интерфейса убедитесь, что PokePointer зарегистрирован в профиле указателя MRTK.
Профиль MRTK по умолчанию и профиль HoloLens 2 по умолчанию уже содержат PokePointer. Чтобы убедиться, что PokePointer будет создан, выберите профиль конфигурации MRTK и перейдите в разделПараметры указателявходных>указателей>. Заготовка по умолчанию PokePointer
(Assets/MRTK/SDK/Features/UX/Prefabs/Pointers) должна быть указана с типом контроллерас шарнирной рукой. Пользовательская заготовка PokePointer
может использоваться до тех пор, пока она реализует класс .
3D GameObjects
Существует два разных способа добавления сенсорных взаимодействий в трехмерные объекты GameObject, в зависимости от того, должен ли ваш трехмерный объект иметь только одну плоскость, доступную для касания, или от того, должен ли он быть осязаемым на основе всего коллайдера. Первый способ обычно используется для объектов с BoxColliders, где требуется, чтобы только одна грань коллайдера реагировала на события касания. Другая — для объектов, которые должны быть доступны для касания с любого направления в зависимости от их коллайдера.
Касание с одним лицом
Это полезно для ситуаций, когда только одно лицо должно быть осязаемым. Этот параметр предполагает, что игровой объект имеет BoxCollider. это можно использовать с объектами, не связанными с BoxCollider. В этом случае свойства "Границы" и "Локальный центр" часто задаются вручную для настройки плоскости, допускающей касание (т. е. для границ следует задать ненулевое значение).
В GameObject, который должен быть сенсорным, добавьте BoxCollider и
NearInteractionTouchable
компонент.Если используется интерфейс в приведенном ниже скрипте
IMixedRealityTouchHandler
компонента, установите для параметра Events (Получить) значение Touch (Получить) на касание.Щелкните "Исправить границы" и "Центр исправления".
Для этого объекта или одного из его предков добавьте компонент скрипта, реализующийинтерфейса
IMixedRealityTouchHandler
. Любой предок объекта с параметромNearInteractionTouchable
также сможет получать события указателя.
Примечание
В представлении сцены редактора с выбранным объектом NearInteractionTouchable GameObject обратите внимание на белый квадрат контура и стрелку. Стрелка указывает на "переднюю" часть сенсорного объекта. Контакт с возможностью взаимодействия будет доступен только в этом направлении. Сведения о том, как сделать коллайдер пригодным для касания со всех сторон, см. в разделе о произвольном касании коллайдера.
Произвольное касание коллайдера
Это полезно для ситуаций, когда игровой объект должен быть доступен для касания вдоль всей его стороны коллайдера. Например, это можно использовать для включения сенсорных взаимодействий для объекта с SphereCollider, где весь коллайдер должен быть сенсорным.
В GameObject, который должен быть сенсорным, добавьте коллайдер и
NearInteractionTouchableVolume
компонент.- Если используется интерфейс в приведенном ниже скрипте
IMixedRealityTouchHandler
компонента, установите для параметра Events (Получить) значение Touch (Получить) на касание.
- Если используется интерфейс в приведенном ниже скрипте
Для этого объекта или одного из его предков добавьте компонент скрипта, реализующийинтерфейса
IMixedRealityTouchHandler
. Любой предок объекта с параметромNearInteractionTouchable
также сможет получать события указателя.
Пользовательский интерфейс Unity
Добавьте или убедитесь, что в сцене есть холст UnityUI .
Добавьте
NearInteractionTouchableUnityUI
компонент в GameObject, который должен быть касаемым.- Если используется интерфейс в приведенном ниже скрипте
IMixedRealityTouchHandler
компонента, установите для параметра Events (Получить) значение Touch (Получить) на касание.
- Если используется интерфейс в приведенном ниже скрипте
Для этого объекта или одного из его предков добавьте компонент скрипта, реализующий
IMixedRealityTouchHandler
интерфейс . Любой предок объекта с параметромNearInteractionTouchableUnityUI
также сможет получать события указателя.
Важно!
Объекты могут вести себя неправильно, если они находятся на перекрывающихся объектах холста. Чтобы обеспечить согласованное поведение, никогда не перекрывайте объекты холста в сцене.
Важно!
В компоненте скрипта NearInteractionTouchable
для свойства События для получения есть два варианта: Указатель и Сенсорный. Задайте для параметра События значение Получить значение Указатель , если используется IMixedRealityPointerHandler
интерфейс, и для параметра Touch при использовании IMixedRealityTouchHandler
интерфейса в скрипте компонента, который отвечает или обрабатывает входные события.
Пример сенсорного кода
В приведенном ниже коде демонстрируется monoBehaviour, который можно присоединить к GameObject с NearInteractionTouchable
помощью компонента variant и реагировать на события сенсорного ввода.
public class TouchEventsExample : MonoBehaviour, IMixedRealityTouchHandler
{
public void OnTouchStarted(HandTrackingInputEventData eventData)
{
string ptrName = eventData.Pointer.PointerName;
Debug.Log($"Touch started from {ptrName}");
}
public void OnTouchCompleted(HandTrackingInputEventData eventData) {}
public void OnTouchUpdated(HandTrackingInputEventData eventData) { }
}
Примеры сценариев близкого взаимодействия
События касания
Этот пример создает куб, делает его сенсорным и изменяет цвет при касании.
public static void MakeChangeColorOnTouch(GameObject target)
{
// Add and configure the touchable
var touchable = target.AddComponent<NearInteractionTouchableVolume>();
touchable.EventsToReceive = TouchableEventType.Pointer;
var material = target.GetComponent<Renderer>().material;
// Change color on pointer down and up
var pointerHandler = target.AddComponent<PointerHandler>();
pointerHandler.OnPointerDown.AddListener((e) => material.color = Color.green);
pointerHandler.OnPointerUp.AddListener((e) => material.color = Color.magenta);
}
События захвата
В приведенном ниже примере показано, как сделать GameObject перетаскиваемым. Предполагается, что игровой объект имеет коллайдер.
public static void MakeNearDraggable(GameObject target)
{
// Instantiate and add grabbable
target.AddComponent<NearInteractionGrabbable>();
// Add ability to drag by re-parenting to pointer object on pointer down
var pointerHandler = target.AddComponent<PointerHandler>();
pointerHandler.OnPointerDown.AddListener((e) =>
{
if (e.Pointer is SpherePointer)
{
target.transform.parent = ((SpherePointer)(e.Pointer)).transform;
}
});
pointerHandler.OnPointerUp.AddListener((e) =>
{
if (e.Pointer is SpherePointer)
{
target.transform.parent = null;
}
});
}
Полезные интерфейсы API
NearInteractionGrabbable
NearInteractionTouchable
NearInteractionTouchableUnityUI
NearInteractionTouchableVolume
IMixedRealityTouchHandler
IMixedRealityPointerHandler