FAQ для систем ввода и событий с UI Toolkit
Эта страница содержит часто задаваемые вопросы по использованию системы событий и системы ввода с UI Toolkit.
- Как узнать, находится ли курсор мыши над визуальным элементом панели времени выполнения?
- Как перенастроить основные действия UI?
- Как изменить, на каком элементе будет фокус следующий при использовании направленной навигации?
- Можно ли избавиться от WASD входов для направленной навигации или пробел для действия submit?
- Как я могу начать ввод с клавиатуры, не нажимая ни на одну точку мыши?
Как узнать, находится ли курсор мыши над визуальным элементом на панели времени выполнения?
Чтобы определить, находится ли курсор мыши над визуальным элементом на панели времени выполнения, используйте один из следующих двух методов:
- Метод 1 использует Event System для автоматического обнаружения и хорошо работает со смешанными uGUI и UI Toolkit UI.
- Способ 2 дает вам ручное управление и полезен, если вам нужно обрабатывать несколько панелей самостоятельно.
Метод 1. Использование системы событий
Элементы UI Toolkit, такие как Button или Label, не являются GameObjects, так что они не передают или не назначают VisualElement переменной GameObject. Используйте Event System, чтобы найти панель, затем используйте UI Toolkit APIs, чтобы найти визуальный элемент под указателем.
Добавление компонента Event System в сцену так же, как и создание GameObjectна основе UI содержимое из
com.unity.uGUIпакет.Используйте метод
EventSystem.current.IsPointerOverGameObject, который возвращаетtrue, если указатель находится над содержимым UI либо из uGUI, либо из UI Toolkit.Чтобы точно перечислить объекты, находящиеся под указателем, используйте метод
EventSystem.current.RaycastAll.-
Найдите панель под указателем. Каждая пересекающаяся панель UI Toolkit представлена панелью GameObject в среде Event System:
- Имя GameObject соответствует соответствующему PanelSettings.
- Родителем GameObject является GameObject, который содержит текущий компонент Event System.
- GameObject состоит из двух компонентов,
PanelRaycasterиPanelEventHandler. Оба компонента имеют свойствоpanel, которое возвращаетIPanel, на который оно направлено.
Вызов метода
panel.Pick, чтобы узнать, какой визуальный элемент находится в позиции указателя.-
Используйте метод
RuntimePanelUtils.ScreenToPanelдля преобразования координат экрана указателя в координаты панели.Примечание: uGUI использует левый нижний источник для координат экрана, в то время как UI Toolkit Для преобразования между ними зеркально измените координаты Y:
yTopLeft = Screen.height - yBottomLeft.
Метод 2. Ручной поиск панели
- Создайте список всех активных панелей в вашей сцене. Для этого проитеруйте все компоненты
UIDocumentв вашей сцене и добавьтеuiDocument.rootVisualElement.panelв список. Если несколько документов имеют одно и то же значение PanelSettings, включите только один документ для каждого различного значения PanelSettings. - Итерация по списку панелей в порядке глубины от верхней до нижней.
- Для каждой панели вызовите
panel.Pickдо тех пор, пока не найдете такую, которая возвращает визуальный элемент.
Как я могу перенастроить основные действия UI?
Чтобы пересопоставить основные действия UI:
- Добавление компонента Event System в сцену так же, как и создание GameObjectна основе UI содержимое из
com.unity.uGUIпакет. - В окне Inspector настройте поля Автономный модуль ввода или Input System UI Модуль ввода, чтобы управлять сопоставлением ввода каждому действию.
Примечание: Действия, сопоставленные с Tab и Shift+Tab входы не могут быть перенанесены, потому что они не подвергаются воздействию через модули ввода Event System.
Как я могу изменить, какой элемент будет фокусироваться следующим при использовании направленной навигации?
Можно настроить направленную навигацию, чтобы иметь другие цели, помимо тех, которые указаны по умолчанию.
Следующий пример кода позволяет элементу A перемещаться к элементам U, D, L, R при перемещении вверх, вниз, влево и вправо соответственно:
A.RegisterCallback <NavigationMoveEvent>(e =>
{
switch(e.direction)
{
case NavigationMoveEvent.Direction.Up: U.Focus(); break;
case NavigationMoveEvent.Direction.Down: D.Focus(); break;
case NavigationMoveEvent.Direction.Left: L.Focus(); break;
case NavigationMoveEvent.Direction.Right: R.Focus(); break;
}
e.StopPropagation(); // Prevent further processing of the event
A.focusController.IgnoreEvent(e); // Prevent default navigation
});
Можно ли избавиться от WASD входов для направленной навигации или пробел для действия submit?
Да. Вы можете использовать EventSystem’s StandaloneInputModule или InputSystemUIInputModule на местах Inspector окно, чтобы управлять тем, какие вводные данные сопоставляются с каждым действием. Однако, поскольку эти действия uGUI ввода, это также изменяет uGUI контроля.
Чтобы перенастроить входы UI Toolkit без изменения элемента управления uGUI, отключите обработку событий времени выполнения UI Toolkit и отправляйте все события вручную на панели. Для этого вызовите EventSystem.SetUITookitEventSystemOverride(null, false, false); до того, как начнет работать метод запуска вашего текущего EventSystem, например, метод Awake компонента вашей сцены. Дополнительную информацию об этом методе uGUI см. в SetUITookitEventSystemOverride.
Как я могу начать ввод с клавиатуры, не нажимая ни на что мышей?
Возможно, что ни один элемент или панель не находится в фокусе в данный момент, например, при первой загрузке игровой сцены. В этом случае навигация с помощью клавиатуры не начинается с предсказуемого первого элемента. Это может быть проблемой для игры, которая играется полностью без мыши.
Чтобы обеспечить предсказуемое поведение навигации с самого начала, добавьте скрипт C# и прикрепите его к тому же скрипту GameObject, что и скрипт UIDocument, ответственный за элемент, который вы выбрали для получения первоначального фокуса.
Предположим, что ваш скрипт называется FirstFocus и ваш первоначальный фокусируемый элемент называется first-focused. В методе Start() вашего скрипт добавьте строку для фокусирования этого элемента следующим образом:
public class FirstFocus : MonoBehaviour
{
void Start()
{
FocusFirstElement();
}
public void FocusFirstElement()
{
GetComponent<UIDocument>().rootVisualElement.
Q<VisualElement>("first-focused").Focus();
}
}
Примечание: Если вы отключите UIDocument’s GameObject, вся его базовая иерархия воссоздается с нуля. Поэтому вам необходимо запустить свой пользовательский FocusFirstElement() метод снова после того, как вы снова включите GameObject.