Работа с EventSystem в Unity. Базовые вещи в работе с UI

    Всем привет! Давно ничего не писал, но сейчас захотелось рассказать про очень удобную штуку, о которой многие не знают. Это Event System в Unity. Многие, для задач в которых EventSystem очень удобен, используют обычный Raycast. Я расскажу про то, как пользоваться частью функционала EventSystem (его на самом деле очень много) и как этот инструмент позволяет быстро решать многие задачи связанные с обработкой событий интерфейсов и объектов. Как всегда с репозиторием с примерами. Если вам интересно — добро пожаловать под кат!



    В данной статье я разберу и предоставлю примеры работы с событиями IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IDragHandler, IBeginDragHandler, IEndDragHandler (полный список событий можно посмотреть тут).

    Что же такое EventSystem? EventSystem — это система отвечающая за обработку разных событий в сцене. В основном она позволяет:

    • Определять какой GameObject “выбран”
    • Управлять способами ввода которые используются
    • Управлять рейкастингом

    Подробнее всего в данной статье мы разберём третий пункт, так как он самый простой и удобный в использовании.

    С точки зрения рейкастов в EventSystem доступны три основных компонента:

    • Graphic Raycaster — используется для работы с UI
    • Physics 2D Raycaster — используется для взаимодействия с физическими объектами в 2D
    • Physics Raycaster — используется для взаимодействия с физическими объектами в 3D

    Важная деталь для всех взаимодействий будь то физика или ui необходимо чтобы объект EventSystem присутствовал на сцене.



    Начнём с самого простого — с UI системы. С ней EventSystem работает проще всего и лучше всего. Дело в том, что при создании Canvas юнити сразу добавляет на сцену все необходимые компоненты, такие как сам EventSystem и Graphic Raycaster.

    В случае с UI, событийная система позволяет легко создавать свои кнопки и базовые взаимодействия с разными UI элементами. Для примера разберём IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IDragHandler, IBeginDragHandler, IEndDragHandler.

    Чтобы UI элемент реагировал на события входа (IPointerEnterHandler), выхода (IPointerExitHandler) курсора мыши необходимо имплементировать эти интерфейсы в необходимый объект. Это помогает во многих случаях, когда нужно что-то выбрать, подсветить и т.п. На примере с тестовой сценой и Image это позволяет сделать интеракции вроде такой в несколько строк кода:

    	public void OnPointerEnter(PointerEventData eventData)
    	{
    		_Image.color = Color.blue;
    	}
    
    	public void OnPointerExit(PointerEventData eventData)
    	{
    		_Image.color = Color.white;
    	}
    



    Для обработки событий нажатия на UI элемент есть два других интерфейса IPointerDownHandler, IPointerUpHandler.

    Их имплементация позволяет в удобном виде обрабатывать события нажатия на объект мышью или тача на мобильных платформах:

    	public void OnPointerDown(PointerEventData eventData)
    	{
    		_Image.color = Color.green;
    	}
    
    	public void OnPointerUp(PointerEventData eventData)
    	{
    		_Image.color = Color.red;
    	}
    



    EventSystem работает с любым компонентом UI системы, который может быть RaycastTarget. Для примера Text и событие клика IPointerClickHandler (важно, это событие похоже на IPointerUpHandler, то есть срабатывает в момент поднятия мыши, но отличие заключается в том, что “отпускание” курсора должно происходить строго в границах объекта):

    using UnityEngine;
    using UnityEngine.EventSystems;
    using UnityEngine.UI;
    
    [RequireComponent(typeof(Text))]
    public class UITextExample : MonoBehaviour, IPointerClickHandler
    {
    	private Text _Text;
    	private bool _IsClicked;
    	private void Start ()
    	{
    		_Text = GetComponent<Text>();
    	}
    
    	public void OnPointerClick(PointerEventData eventData)
    	{
    		_Text.text = _IsClicked ? "Hello there!" : "General Kenobi";
    		_IsClicked = !_IsClicked;
    	}
    }
    



    Самыми интересными ивентами на мой взгляд, являются те, что позволяют удобно делать Drag. Это набор интерфейсов IDragHandler, IBeginDragHandler, IEndDragHandler. С ними так же всё очень просто. Визуальный эффект сильно зависит от способа обработки, но эти три события позволяют делать самые разные взаймодействия за несколько минут. В случае, если элемент, который вы собираетесь двигать состоит из разных UI элементов, важно отключать галочку RaycastTarget на тех элементах, которые не являются интерактивными. (Важно: в случае с UI системой нужно использовать screenPosition из PointerEventData которая приходит во всех методах событийной системы связанных с мышью/тачем)

    public class UIDragExample : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
    {
        [SerializeField] private Text _Text;
        public void OnDrag(PointerEventData eventData)
        {
            transform.position = eventData.pointerCurrentRaycast.screenPosition;
        }
    
        public void OnBeginDrag(PointerEventData eventData)
        {
            _Text.text = "You dragging!";
        }
    
        public void OnEndDrag(PointerEventData eventData)
        {
            _Text.text = "Drag me!";
        }
    }
    



    В общем то по UI системе всё, на самом деле там есть ещё несколько полезных штук с точки зрения Event System, но про них я может напишу в будущих статьях.

    Работа с физическими объектами отличается лишь двумя пунктами. Первое — надо внимательно следить, чтобы объект EventSystem был на сцене, чтобы это работало. Второе — надо повесить компонент PhysicsRaycaster на основную камеру, чтобы всё это так же работало по коллайдерам. В остальном почти тоже самое, простенький пример вы можете найти в репозитории.

    В общем EventSystem крутой и удобный инструмент, который позволяет многие вещи делать в разы быстрее нежели обычными рейкастами. Кроме того в EventSystem есть очень много полезного функционала вроде того, что там можно переопределять инпуты (к примеру вас интересует специфичный контроллер, скажем Leap Motion) и многое другое, о чём я может напишу в будущих статьях.

    Спасибо за внимание!
    • +20
    • 9,1k
    • 5
    Поделиться публикацией
    Комментарии 5
      –7
      годнота!
        +1
        Зашел в статью, думал, будет откровение или хотя бы анализ разных решений с цифрами, а тут глава из методички: «EventSystem для самых маленьких». Для тех, кто побольше, есть официальный мануал.
          0
          Совершенно верно. Возможно я слишком плохо написал название. Его суть в том, что мне надоело видеть в большинстве решений Physics.Raycast на физические объекты для банального hover'а мышкой, поэтому я написал статью о том, что есть такая великолепная штука, как EventSystem
            0
            Собственно об этом написано до ката. Возможно стоило вписать пример с физикой, а не вынести его в репозиторий. А так, эта статья именно для новичков, чтобы они знали что существует такой инструмент и представляли, как им можно пользоваться.
            +2
            Прекратите использовать рейкасты там, где это не нужно!

            Не раскрыты критерии нужности и ненужности. IxxxHandler ― полезная альтернатива рейкастам, но возникает два вопроса: так ли объектам нужно знать, что по ним кликнули, и кто должен обрабатывать эти клики?


            Допустим, есть дверь. По двери можно кликнуть, чтобы её выделить, чтобы её удалить, чтобы дать команду персонажу её открыть, закрыть, отпереть, запереть, атаковать. А ещё пользователь может кликнуть по двери в момент, когда никакой реакции на такое действие не предполагается вообще.


            Имхо, скрипт двери должен уметь её открыть, закрыть, хранить текущее состояние и, может быть, список подходящих ключей. А о существовании персонажей или когда по двери можно кликать, а когда нельзя, скрипту знать не надо. Пусть лучше пользовательским вводом и его обработкой занимаются другие подсистемы.


            имплементация

            Реализация.


            интеракции

            Взаимодействия.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое