Интерактивный элемент [экспериментальный] — MRTK2
Упрощенная централизованная точка входа в систему ввода MRTK. Содержит методы управления состоянием, управление событиями и логику настройки состояния для основных состояний взаимодействия.
Интерактивный элемент — это экспериментальная функция, поддерживаемая в Unity 2019.3 и более поздней версии, так как в ней используется новая возможность Unity 2019.3: Сериализация справочника.
Инспектор интерактивных элементов
В режиме воспроизведения инспектор интерактивных элементов предоставляет визуальную обратную связь, показывающую, активно ли текущее состояние. Если состояние активно, оно будет выделено голубой цветом. Если состояние неактивно, цвет не изменяется. Числа рядом с состояниями в инспекторе являются значениями состояния. Если состояние активно, то значение равно 1, если состояние неактивно, значение равно 0.
Основные состояния
Интерактивный элемент содержит основные состояния и поддерживает добавление пользовательских состояний. Основное состояние — это состояние, которое уже имеет логику настройки состояния, определенную в BaseInteractiveElement
. Ниже приведен список текущих основных состояний, управляемых входными данными.
Текущие основные состояния
Основные состояния ближнего и дальнего взаимодействия:
Основные состояния ближнего взаимодействия:
Основные состояния дальнего взаимодействия:
Другие основные состояния:
Добавление основного состояния с помощью Inspector
Перейдите к разделу Добавление основного состояния в инспекторе для элемента Interactive.
Нажмите кнопку Выбрать состояние , чтобы выбрать основное состояние для добавления. Состояния в меню отсортированы по типу взаимодействия.
Откройте складку Конфигурации событий, чтобы просмотреть события и свойства, связанные с состоянием.
Добавление основного состояния с помощью скрипта
Используйте метод , AddNewState(stateName)
чтобы добавить основное состояние. Чтобы получить список доступных имен основных состояний, используйте перечисление CoreInteractionState
.
// Add by name or add by CoreInteractionState enum to string
interactiveElement.AddNewState("SelectFar");
interactiveElement.AddNewState(CoreInteractionState.SelectFar.ToString());
Внутренняя структура состояний
Состояния в интерактивном элементе имеют тип InteractionState
. Содержит InteractionState
следующие свойства:
- Имя: имя состояния.
- Значение: значение состояния. Если состояние включено, значение состояния равно 1. Если состояние выключено, значение состояния равно 0.
- Активный. Указывает, активно ли состояние в данный момент. Значение свойства Active имеет значение true, если состояние включено, и false, если состояние отключено.
- Тип взаимодействия. Тип взаимодействия состояния — это тип взаимодействия, для который предназначено состояние.
None
: не поддерживает какие-либо формы взаимодействия ввода.Near
: поддержка близкого взаимодействия. Ввод считается ближайшим взаимодействием, когда рука имеет прямой контакт с другим игровым объектом, т. е. положение руки близко к положению игрового объекта в мировом пространстве.Far
: поддержка удаленного взаимодействия. Входные данные считаются дальним взаимодействием, если прямой контакт с игровым объектом не требуется. Например, входные данные через луч контроллера или взгляд считаются входными данными дальнего взаимодействия.NearAndFar
: включает поддержку ближнего и дальнего взаимодействия.Other
: поддержка независимого взаимодействия с указателем.
- Конфигурация событий. Конфигурация событий для состояния — это точка входа в профиль сериализованных событий.
Все эти свойства задаются внутри объекта , State Manager
содержащегося в элементе Interactive. Для изменения состояний используйте следующие вспомогательные методы:
Вспомогательные методы настройки состояния
// Get the InteractionState
interactiveElement.GetState("StateName");
// Set a state value to 1/on
interactiveElement.SetStateOn("StateName");
// Set a state value to 0/off
interactiveElement.SetStateOff("StateName");
// Check if a state is present in the state list
interactiveElement.IsStatePresent("StateName");
// Check whether or not a state is active
interactiveElement.IsStateActive("StateName");
// Add a new state to the state list
interactiveElement.AddNewState("StateName");
// Remove a state from the state list
interactiveElement.RemoveState("StateName");
Получение конфигурации события состояния зависит от самого состояния. Каждое основное состояние имеет определенный тип конфигурации события, описанный ниже в разделах, описывающих каждое основное состояние.
Ниже приведен обобщенный пример получения конфигурации событий состояния:
// T varies depending on the core state - the specific T's are specified under each of the core state sections
T stateNameEvents = interactiveElement.GetStateEvents<T>("StateName");
Состояние по умолчанию
Состояние по умолчанию всегда присутствует в интерактивном элементе. Это состояние будет активным только в том случае, если все остальные состояния неактивны. Если какое-либо другое состояние становится активным, состояние по умолчанию будет внутренне отключено.
Интерактивный элемент инициализируется с состояниями Default и Focus, которые присутствуют в списке состояний. Состояние по умолчанию всегда должно присутствовать в списке состояний.
Получение событий состояния по умолчанию
Тип конфигурации события для состояния по умолчанию: StateEvents
StateEvents defaultEvents = interactiveElement.GetStateEvents<StateEvents>("Default");
defaultEvents.OnStateOn.AddListener(() =>
{
Debug.Log($"{gameObject.name} Default State On");
});
defaultEvents.OnStateOff.AddListener(() =>
{
Debug.Log($"{gameObject.name} Default State Off");
});
Состояние фокуса
Состояние Фокус — это состояние ближнего и дальнего взаимодействия, которое можно рассматривать как смешанную реальность, эквивалентную наведении указателя мыши. Различением ближнего и дальнего взаимодействия для состояния Фокусировка является текущий активный тип указателя. Если типом указателя для состояния фокусировки является указатель покачки, то взаимодействие считается ближайшим взаимодействием. Если основной указатель не является указателем,то взаимодействие считается дальним. Состояние Фокуса по умолчанию присутствует в интерактивном элементе.
Поведение состояния
Получение событий состояния фокуса
Тип конфигурации события для состояния фокуса: FocusEvents
FocusEvents focusEvents = interactiveElement.GetStateEvents<FocusEvents>("Focus");
focusEvents.OnFocusOn.AddListener((pointerEventData) =>
{
Debug.Log($"{gameObject.name} Focus On");
});
focusEvents.OnFocusOff.AddListener((pointerEventData) =>
{
Debug.Log($"{gameObject.name} Focus Off");
});
Поведение фокусировки близкого к фокусу и фокуса на удаленном расположении
Близкое состояние фокуса
Состояние "Фокус вблизи" устанавливается, когда возникает событие фокуса, а основным указателем является указатель", указывающий на близкое взаимодействие.
Фокус рядом с поведением состояния
Фокус вблизи государственного
Получение событий состояния FocusNear
Тип конфигурации события для состояния FocusNear: FocusEvents
FocusEvents focusNearEvents = interactiveElement.GetStateEvents<FocusEvents>("FocusNear");
focusNearEvents.OnFocusOn.AddListener((pointerEventData) =>
{
Debug.Log($"{gameObject.name} Near Interaction Focus On");
});
focusNearEvents.OnFocusOff.AddListener((pointerEventData) =>
{
Debug.Log($"{gameObject.name} Near Interaction Focus Off");
});
Состояние фокусировки на дальних направлениях
Состояние Фокусировка задается, если основной указатель не является указателем Poke. Например, указатель луча контроллера по умолчанию и указатель GGV (взгляд, жест, голос) считаются указателями дальнего взаимодействия.
Состояние фокусировки в режиме "Поведение
Focus Far State Inspector
Получение событий удаленного состояния фокуса
Тип конфигурации события для состояния FocusFar: FocusEvents
FocusEvents focusFarEvents = interactiveElement.GetStateEvents<FocusEvents>("FocusFar");
focusFarEvents.OnFocusOn.AddListener((pointerEventData) =>
{
Debug.Log($"{gameObject.name} Far Interaction Focus On");
});
focusFarEvents.OnFocusOff.AddListener((pointerEventData) =>
{
Debug.Log($"{gameObject.name} Far Interaction Focus Off");
});
Состояние касания
Состояние Касание — это состояние близкого взаимодействия, которое устанавливается, когда членяя рука касается объекта напрямую. Прямое касание означает, что указательный палец руки очень близок к положению в мире объекта. По умолчанию компонент присоединяется к объекту, NearInteractionTouchableVolume
если состояние Touch добавляется в список состояний. Для обнаружения событий касания требуется наличие NearInteractionTouchableVolume
компонента или NearInteractionTouchable
. Разница между NearInteractionTouchableVolume
и NearInteractionTouchable
заключается в том, что NearInteractionTouchableVolume
обнаруживает касание на основе коллайдера объекта и NearInteractionTouchable
обнаруживает касание в определенной области плоскости.
Поведение состояния касания
Инспектор состояний касания
Получение событий состояния касания
Тип конфигурации события для состояния касания: TouchEvents
TouchEvents touchEvents = interactiveElement.GetStateEvents<TouchEvents>("Touch");
touchEvents.OnTouchStarted.AddListener((touchData) =>
{
Debug.Log($"{gameObject.name} Touch Started");
});
touchEvents.OnTouchCompleted.AddListener((touchData) =>
{
Debug.Log($"{gameObject.name} Touch Completed");
});
touchEvents.OnTouchUpdated.AddListener((touchData) =>
{
Debug.Log($"{gameObject.name} Touch Updated");
});
Выбор удаленного состояния
Состояние Select Far (Выбрать даль) является всплывным IMixedRealityPointerHandler
. Это состояние является состоянием дальнего взаимодействия, которое обнаруживает щелчок дальнего взаимодействия (касание) и удерживает за счет использования указателей дальнего взаимодействия, таких как указатель луча контроллера по умолчанию или указатель GGV. Состояние Select Far имеет параметр в складной части конфигурации события с именем Global
. Если Global
имеет значение true, то IMixedRealityPointerHandler
регистрируется как глобальный обработчик входных данных. Фокусировка на объекте не требуется для активации системных событий ввода, если обработчик зарегистрирован как глобальный. Например, если пользователь хочет узнать, когда выполняется жест касания/выбора, независимо от объекта в фокусе, задайте для параметра Global
значение true.
Выбор поведения в удаленном состоянии
Выберите Far State Inspector
Получение событий Select Far State
Тип конфигурации события для состояния SelectFar: SelectFarEvents
SelectFarEvents selectFarEvents = interactiveElement.GetStateEvents<SelectFarEvents>("SelectFar");
selectFarEvents.OnSelectUp.AddListener((pointerEventData) =>
{
Debug.Log($"{gameObject.name} Far Interaction Pointer Up");
});
selectFarEvents.OnSelectDown.AddListener((pointerEventData) =>
{
Debug.Log($"{gameObject.name} Far Interaction Pointer Down");
});
selectFarEvents.OnSelectHold.AddListener((pointerEventData) =>
{
Debug.Log($"{gameObject.name} Far Interaction Pointer Hold");
});
selectFarEvents.OnSelectClicked.AddListener((pointerEventData) =>
{
Debug.Log($"{gameObject.name} Far Interaction Pointer Clicked");
});
Состояние нажатой кнопки
Состояние Clicked по умолчанию активируется нажатием кнопки удаленного взаимодействия (выбрать состояние "Далеко") . Это состояние внутренне переключается на включено, вызывает событие OnClicked, а затем немедленно выключается.
Примечание
Визуальная обратная связь в инспекторе на основе действия состояния отсутствует для состояния Clicked, так как она включается, а затем немедленно отключается.
Поведение щелкнутого состояния
Щелкнул Инспектор
Пример состояния ближнего и дальнего щелчка
Состояние щелчка можно активировать через дополнительные точки входа с помощью interactiveElement.TriggerClickedState()
метода . Например, если пользователь хочет, чтобы сенсорный ввод близкого взаимодействия также активировал щелчок по объекту, он добавит TriggerClickedState()
метод в качестве прослушивателя в состоянии сенсорного ввода.
Получение событий состояния щелчка
Тип конфигурации события для состояния clicked: ClickedEvents
ClickedEvents clickedEvent = interactiveElement.GetStateEvents<ClickedEvents>("Clicked");
clickedEvent.OnClicked.AddListener(() =>
{
Debug.Log($"{gameObject.name} Clicked");
});
Включение и выключение состояния
Состояния Toggle On (Вкл.) и Toggle Off (Выключить) — это пара, и оба состояния должны присутствовать для поведения переключателя. По умолчанию состояния Включить и Выключить активируются с помощью щелчка по удаленному взаимодействию (Выбрать далекое состояние). По умолчанию состояние Выключение активно при запуске, что означает, что переключатель будет инициализирован в положение "Выкл.". Если пользователь хочет, чтобы состояние Toggle On было активным при запуске, то для свойства Toggle On state (Включить) установите значение IsSelectedOnStart
true.
Режим toggleOn и Toggle Off State
ToggleOn and ToggleOn and Toggle Off State Inspector
Пример состояний ближнего и дальнего переключения
Как и в случае с состоянием Clicked, параметр состояния переключения может иметь несколько точек входа с помощью interactiveElement.SetToggleStates()
метода . Например, если пользователь хочет, чтобы сенсорный ввод был дополнительной точкой входа для установки состояний переключателя, он добавляет SetToggleStates()
метод в одно из событий в состоянии Touch.
Получение событий состояния включения и выключения
Тип конфигурации события для состояния ToggleOn: ToggleOnEvents
Тип конфигурации события для состояния ToggleOff: ToggleOffEvents
// Toggle On Events
ToggleOnEvents toggleOnEvent = interactiveElement.GetStateEvents<ToggleOnEvents>("ToggleOn");
toggleOnEvent.OnToggleOn.AddListener(() =>
{
Debug.Log($"{gameObject.name} Toggled On");
});
// Toggle Off Events
ToggleOffEvents toggleOffEvent = interactiveElement.GetStateEvents<ToggleOffEvents>("ToggleOff");
toggleOffEvent.OnToggleOff.AddListener(() =>
{
Debug.Log($"{gameObject.name} Toggled Off");
});
Состояние ключевого слова "Речь"
Состояние ключевого слова "Речь" прослушивает ключевые слова, определенные в профиле речи Смешанная реальность. Все новые ключевое слово ДОЛЖНЫ быть зарегистрированы в профиле голосовой команды перед выполнением (шаги ниже).
Поведение ключевых слов службы "Речь"
Компонент ключевое слово службы "Речь" с ключевым словом State Inspector
Примечание
Состояние ключевого слова speech было активировано в редакторе нажатием клавиши F5 в GIF-файле выше. Ниже описаны действия по настройке в редакторе тестирования речи.
Регистрация команды или ключевого слова службы "Речь"
Выбор игрового объекта MixedRealityToolkit
Выберите Копировать и настроить текущий профиль.
Перейдите в раздел Входные данные и выберите Клонировать , чтобы включить изменение профиля ввода.
Прокрутите вниз до раздела "Речь" в профиле ввода и клонируйте профиль речи.
Выберите Add a New Speech Command (Добавить новую голосовую команду).
Введите новый ключевое слово. Необязательно. Измените значение keyCode на F5 (или другой код ключа), чтобы разрешить тестирование в редакторе.
Назад в инспектор состояния ключевых слов службы "Речь" интерактивного элемента и выберите Добавить ключевое слово
Введите новый ключевое слово, который был только что зарегистрирован в профиле службы "Речь"
Чтобы проверить состояние ключевого слова речи в редакторе, нажмите ключевой код, определенный на шаге 6 (F5), чтобы имитировать распознанное событие ключевое слово речи.
Получение событий состояния ключевых слов службы "Речь"
Тип конфигурации события для состояния SpeechKeyword: SpeechKeywordEvents
SpeechKeywordEvents speechKeywordEvents = interactiveElement.GetStateEvents<SpeechKeywordEvents>("SpeechKeyword");
speechKeywordEvents.OnAnySpeechKeywordRecognized.AddListener((speechEventData) =>
{
Debug.Log($"{speechEventData.Command.Keyword} recognized");
});
// Get the "Change" Keyword event specifically
KeywordEvent keywordEvent = speechKeywordEvents.Keywords.Find((keyword) => keyword.Keyword == "Change");
keywordEvent.OnKeywordRecognized.AddListener(() =>
{
Debug.Log("Change Keyword Recognized");
});
Пользовательские состояния
Создание пользовательского состояния с помощью Inspector
Пользовательское состояние, созданное с помощью inspector, будет инициализировано с конфигурацией события состояния по умолчанию. Конфигурация событий по умолчанию для пользовательского состояния имеет тип StateEvents
и содержит события OnStateOn и OnStateOff.
Перейдите в раздел Создание пользовательского состояния в инспекторе для интерактивного элемента.
Введите имя нового состояния. Это имя должно быть уникальным и не может совпадать с существующими основными состояниями.
Выберите Задать имя состояния , чтобы добавить его в список состояний.
Это настраиваемое состояние инициализируется конфигурацией событий по умолчанию
StateEvents
, которая содержитOnStateOn
события иOnStateOff
. Сведения о создании настраиваемой конфигурации событий для нового состояния см. в статье Создание пользовательского состояния с помощью пользовательской конфигурации событий.
Создание пользовательского состояния с помощью скрипта
interactiveElement.AddNewState("MyNewState");
// A new state by default is initialized with a the default StateEvents configuration which contains the
// OnStateOn and OnStateOff events
StateEvents myNewStateEvents = interactiveElement.GetStateEvents<StateEvents>("MyNewState");
myNewStateEvents.OnStateOn.AddListener(() =>
{
Debug.Log($"MyNewState is On");
});
Создание пользовательского состояния с помощью конфигурации пользовательских событий
Примеры файлов для пользовательского состояния с именем Keyboard находятся здесь: MRTK\SDK\Experimental\InteractiveElement\Examples\Scripts\CustomStateExample
Ниже описан существующий пример создания конфигурации пользовательского события состояния и файлов получателей.
Подумайте о названии штата. Это имя должно быть уникальным и не может совпадать с существующими основными состояниями. В этом примере используется имя состояния Keyboard.
Создайте два CS-файла с именем state name + "Receiver" и state name + "Events". Имена этих файлов учитываются внутри организации и должны соответствовать соглашению имя состояния + событие/приемник.
Дополнительные сведения о содержимом файлов см. в файлах KeyboardEvents.cs и KeyboardReceiver.cs. Новые классы конфигурации событий должны наследовать от
BaseInteractionEventConfiguration
, а новые классы приемников событий — отBaseEventReceiver
. Примеры настройки состояния для состояния клавиатуры находятся вCustomStateSettingExample.cs
файле .Добавьте состояние в интерактивный элемент, используя имя состояния. Имя состояния будет распознано, если существуют файлы конфигурации события и приемника событий. Свойства в файле конфигурации пользовательского события должны отображаться в инспекторе.
Дополнительные примеры конфигурации событий и файлов приемников событий см. в файлах по следующим путям:
- MRTK\SDK\Experimental\InteractiveElement\InteractiveElement\Events\EventConfigurations
- MRTK\SDK\Experimental\InteractiveElement\InteractiveElement\Events\EventReceivers
Пример сцены
Пример сцены для интерактивного элемента и визуализатора состояния находится здесь: MRTK\SDK\Experimental\InteractiveElement\Examples\InteractiveElementExampleScene.unity
Сжимаемая кнопка
Пример сцены содержит заготовки с именами CompressableButton
и CompressableButtonToggle
, эти заготовки зеркало поведение кнопок, созданных с помощью интерактивного PressableButtonHoloLens2
элемента и визуализатора состояния.
Компонент CompressableButton
в настоящее время является сочетаниемPressableButtonHoloLens2
PressableButton
+ с в BaseInteractiveElement
качестве базового класса.
Визуализатор состояния [экспериментальный]
Компонент Визуализатор состояния добавляет анимации к объекту на основе состояний, определенных в связанном компоненте interactive Element. Этот компонент создает ресурсы анимации, помещает их в папку MixedRealityToolkit.Generated и включает упрощенный параметр ключевого кадра анимации путем добавления свойств Animatable к целевому объекту игры. Чтобы включить переходы анимации между состояниями, создается ресурс контроллера animator и создается конечный автомат по умолчанию со связанными параметрами и любыми переходами состояния. Конечный автомат можно просмотреть в окне аниматора Unity.
Визуализатор состояния и система анимации Unity
В настоящее время визуализатор состояния использует систему анимации Unity.
При нажатии кнопки Создать новые клипы анимации в визуализаторе состояния новые ресурсы клипов анимации создаются на основе имен состояний в интерактивном элементе и помещаются в папку MixedRealityToolkit.Generated. Свойству Анимационный клип в каждом контейнере состояния присваивается связанный клип анимации.
Для управления плавными переходами между клипами анимации также создается конечный автомат аниматора . По умолчанию конечный автомат использует любое состояние , чтобы разрешить переходы между любым состоянием в интерактивном элементе.
Визуализаторы состояния, активируемые в аниматоре , также создаются для каждого состояния. Параметры триггера используются в визуализаторе состояния для запуска анимации.
Ограничения среды выполнения
Визуализатор состояния должен быть добавлен в объект с помощью инспектора и не может быть добавлен с помощью скрипта. Свойства, которые изменяют AnimatorStateMachine/AnimationController, содержатся в пространстве имен редактора (UnityEditor.Animations
), которое удаляется при сборке приложения.
Использование визуализатора состояния
Создание куба
Элемент Attach Interactive
Визуализатор состояния присоединения
Выберите Создать новые клипы анимации.
В контейнере Состояние фокуса выберите Добавить целевой объект.
Перетащите текущий игровой объект в целевое поле
Открытие складной части анимируемых свойств куба
Выберите раскрывающееся меню Анимируемое свойство и выберите Цвет.
Выберите Add the Color Animatable Property (Добавить свойство color Animatable)
Выбор цвета
Нажмите кнопку воспроизведения и наблюдайте за переходным изменением цвета
Анимируемые свойства
Основная цель анимируемых свойств — упростить настройку ключевого кадра клипа анимации. Если пользователь знаком с системой анимации Unity и предпочитает напрямую задавать ключевые кадры для созданных клипов анимации, он может просто не добавлять свойства Animatable к целевому объекту и открывать клип в окне анимации Unity (Анимация анимации > Windows>).
Если для анимации используются свойства Animatable, тип кривой имеет значение EaseInOut.
Текущие анимируемые свойства:
Смещение масштаба
Свойство Scale Offset Animatable принимает текущий масштаб объекта и добавляет определенное смещение.
Смещение позиции
Анимируемое свойство Position Offset принимает текущую позицию объекта и добавляет определенное смещение.
Цвет
Свойство Color Animatable представляет main цвет материала, если материал имеет свойство цвета main. Это свойство анимирует material._Color
свойство .
Цвет шейдера
Свойство шейдера Color Animatable ссылается на свойство шейдера типа color. Имя свойства является обязательным для всех свойств шейдера. В приведенном ниже gif демонстрируется анимация свойства цвета шейдера с именем Fill_Color, которое не является цветом main материала. Наблюдайте за изменениями значений в инспекторе материалов.
Float шейдера
Свойство Shader Float Animatable ссылается на свойство шейдера типа float. Имя свойства является обязательным для всех свойств шейдера. В приведенном ниже GIF-файле обратите внимание на изменение значений в инспекторе материалов для свойства Metallic.
Вектор шейдера
Свойство Shader Vector Animatable ссылается на свойство шейдера типа Vector4. Имя свойства является обязательным для всех свойств шейдера. В приведенном ниже GIF-файле обратите внимание на изменение значений в инспекторе материалов для свойства Tiling (Main Tex_ST).
Поиск имен свойств анимируемого шейдера
Переход к анимации > окна >
Убедитесь, что в иерархии выбран объект с визуализатором состояния.
Выберите любой клип анимации в окне Анимация
Выберите Добавить свойство, откройте развертку отрисовщика сетки
Этот список содержит имена всех анимируемых свойств.