#UI-GD [Doc Unity](https://docs.unity3d.com/ru/2018.4/ScriptReference/EventSystems.EventSystem.html) [habr](https://habr.com/ru/articles/359106/) EventSystem играет центральную роль в обработке событий ввода и управлении пользовательским интерфейсом в Unity. Он отвечает за распределение событий и координацию взаимодействия между различными компонентами, такими как StandaloneInputModule, GraphicRaycaster и UI-элементами. EventSystem необходим для обработки пользовательского ввода, такого как нажатия кнопок, перемещение курсора, скроллинг и выделение объектов пользовательского интерфейса. Без EventSystem UI-элементы не смогут реагировать на взаимодействие пользователя и не смогут выполнять свои функции. На сцене может быть только один активный объект EventSystem. Если вы попытаетесь добавить другой EventSystem, Unity предупредит вас об этом и автоматически удалит лишний объект. С точки зрения рейкастов в EventSystem доступны три основных компонента: * Graphic Raycaster — используется для работы с UI * Physics 2D Raycaster — используется для взаимодействия с физическими объектами в 2D * Physics Raycaster — используется для взаимодействия с физическими объектами в 3D <br> Важная деталь для всех взаимодействий будь то физика или ui необходимо чтобы gameobject EventSystem присутствовал на сцене. - у EventSystem должны быть компонент EventSystem и StandaloneInputModule (или другой аналогичный модуль ввода). ### Порядок исполнения всех эвентов в EventSystem [Список events в doc unity](https://docs.unity3d.com/ru/2019.4/Manual/SupportedEvents.html) EventSystem в Unity не имеет строго определенного порядка исполнения всех событий, так как порядок вызова событий зависит от конкретной ситуации и взаимодействия с пользовательским интерфейсом. Вот список событий, которые обрабатываются EventSystem: 1. OnPointerEnter 2. OnPointerExit 3. OnPointerDown 4. OnPointerUp 5. OnPointerClick 6. OnBeginDrag 7. OnDrag 8. OnEndDrag 9. OnDrop 10. OnScroll 11. OnUpdateSelected 12. OnSelect 13. OnDeselect 14. OnMove 15. OnSubmit 16. OnCancel Порядок вызова этих событий зависит от действий пользователя и взаимодействия с элементами пользовательского интерфейса. Однако, существует некоторая последовательность вызова событий для определенных сценариев. Например, при перетаскивании элемента пользовательского интерфейса вызывается следующая последовательность событий: 1. OnPointerDown 2. OnBeginDrag 3. OnDrag 4. OnEndDrag 5. OnDrop 6. OnPointerUp Обратите внимание, что порядок вызова может изменяться в зависимости от конкретных условий и взаимодействий. ### Как можно обрабатывать события EventSystem? 1. С помощью компонента Event trigger 2. С помощью интерфейс-обработчиков событий 3. С помощью луча (`EventSystem.current.RaycastAll` или ) Пример реализации интерфейс-обработчика ```csharp using UnityEngine; using UnityEngine.EventSystems; public class MyClickHandler : MonoBehaviour, IPointerClickHandler { public void OnPointerClick(PointerEventData eventData) { Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name); } } ``` <br> ### EventSystem класс Как вызывать все перечисленные ниже мember’s: ```csharp EventSystem.current.RaycastAll(pointerEventData, raycastResults); ``` <br> ```csharp public static EventSystem current ``` Свойство предоставляет доступ к текущей активной системе событий (EventSystem) в вашей сцене. С помощью **EventSystem.current** вы можете получить ссылку на активную систему событий и взаимодействовать с ее методами и свойствами. Например, вы можете проверить, находится ли курсор над объектом пользовательского интерфейса, установить выбранный объект или определить, какой объект сейчас выбран. ```csharp public GameObject currentSelectedGameObject ``` Свойство возвращает ссылку на текущий выбранный GameObject с UI-компонентом. В контексте пользовательского интерфейса, это обычно элемент UI, такой как кнопка, поле ввода или другой интерактивный объект, который в данный момент имеет фокус ввода или активен. ```csharp public GameObject firstSelectedGameObject ``` Свойство хранит ссылку на GameObject с UI-компонентом, который будет автоматически выбран при активации сцены. Обычно это первый интерактивный элемент UI, такой как кнопка или поле ввода, который получает фокус при начале взаимодействия с пользовательским интерфейсом. Свойство позволяет как **set**, так и **get**. Можно установить значение и через инспектор. Выбираете EventSystem на вашей сцене, а затем в инспекторе находите компонент StandaloneInputModule. В поле First Selected вы можете указать ссылку на игровой объект, который должен быть выбран первым при активации данного интерфейса. <br> <br> ```csharp public void SetSelectedGameObject(GameObject selected) ``` Метод используется для установки активного выбранного объекта в системе событий Unity. Это полезно, когда вы работаете с интерактивными элементами пользовательского интерфейса, такими как кнопки, ползунки, выпадающие списки и т. д. Когда объект установлен как выбранный, он будет автоматически получать события ввода, такие как нажатия клавиш, перемещения и события подтверждения/отмены (Enter/Cancel). Это особенно полезно при работе с навигацией по пользовательскому интерфейсу с помощью клавиатуры, геймпада или других устройств ввода, отличных от мыши. <br> ```csharp public bool IsPointerOverGameObject() public bool IsPointerOverGameObject(int pointerId) ``` <u>Первая сигнатура</u> Возвращает значение true, если указатель мыши или сенсорного экрана находится над объектом любым UI, и false в противном случае. <u>Вторая сигнатура</u> Возвращает значение true, если указатель мыши или сенсорного экрана с указанным идентификатором указателя находится над объектом пользовательского интерфейса, и false в противном случае. Пример ```csharp if (EventSystem.current.IsPointerOverGameObject()) { // Указатель мыши находится над UI-GameObject. } ``` <br> ```csharp public void RaycastAll(PointerEventData eventData, List<RaycastResult> raycastResults) ``` Также посмотри заметку [В чем разница между graphicRaycaster.Raycast и EventSystem.current.RaycastAll](В%20чем%20разница%20между%20graphicRaycaster.Raycast%20и%20EventSystem.current.RaycastAll.md). Метод **RaycastAll** используется для определения UI-GameObject’ов, которые пересекаются с указателем (например, курсором мыши), и которые могут принять какие-либо события ввода, такие как нажатия кнопок, нажатия мыши и т.д. Это полезно, когда вам нужно определить, какой элемент UI должен реагировать на действия пользователя. Метод выполняет рейкастинг (трассировку луча) из позиции указателя через UI-элементы на сцене. Все объекты, которые пересекаются с этим лучом, добавляются в список результатов (raycastResults). Затем система событий может определить, какой из пересекающихся элементов UI должен получить ввод, обычно на основе порядка сортировки или других факторов, таких как настройки блокировки указателя. Тем самым метод позволяет обрабатывать сложные сценарии, в которых элементы UI могут быть наложены друг на друга или скрыты за другими элементами. **eventData** - Это данные, связанные с событием указателя (например, позиция указателя, клик, нажатие и т. д.). Передается в метод, чтобы определить точку начала и направление рейкастинга. **raycastResults** - Это список, в который будут добавлены результаты рейкастинга. Пример использования **RaycastAll** для определения элемента UI, на который нажал пользователь: ```csharp public class RaycastExample : MonoBehaviour { private GraphicRaycaster graphicRaycaster; private PointerEventData pointerEventData; private EventSystem eventSystem; void Start() { graphicRaycaster = GetComponent<GraphicRaycaster>(); eventSystem = FindObjectOfType<EventSystem>(); } void Update() { if (Input.GetMouseButtonDown(0)) { pointerEventData = new PointerEventData(eventSystem); pointerEventData.position = Input.mousePosition; List<RaycastResult> results = new List<RaycastResult>(); graphicRaycaster.Raycast(pointerEventData, results); foreach (RaycastResult result in results) { Debug.Log("Hit: " + result.gameObject.name); } } } } ``` 1. В Unity, добавьте компонент Canvas на сцену, если его еще нет. 2. Добавьте на канвас несколько элементов UI, таких как кнопки или панели. 3. Выберите канвас и добавьте созданный скрипт "RaycastExample" в качестве компонента. 4. Запустите сцену и нажмите на элементы UI. В окне консоли вы увидите имена элементов UI, с которыми пересекся луч. <br> <br> ```csharp public void UpdateModules() public bool alreadySelecting ``` <u>Первый метод:</u> Метод, который обновляет активные модули ввода, такие как StandaloneInputModule. <u>Второй метод:</u> Возвращает значение true, если событийная система уже выбирает объект UI, и false в противном случае. Не стал подробно расписывать, потому что GPT-4 сказал, что: Эти методы обычно используются внутри самого класса EventSystem или в коде, который работает непосредственно с системой событий, и возможно, не имеют прямого применения в большинстве пользовательских сценариев.