Стики и работа с Event System в Unity 3D
Учебные материалы для школы программирования. Часть 12
Предыдущие уроки можно найти здесь:Этот материал состоит из двух частей:
В первой, рассмотрим создание удобных стиков, подходящих под любые разрешения экранов и любую диагональ.
Познакомимся с использованием Event System в разрезе работы с UI и реализации пользовательской обработки реакции на указатель мыши/тачпада.
Далее, перейдем ко второй, где создадим скрипт, реализующий доступ к другим объектам посредством Event System.
По ходу дела, попробуем свои силы в работе со static-переменными для реализации удобной имплементации модулей в проект, и узнаем о глобальных и локальных координатах RectTransform.
Обе части занятия являют собой продолжение работы над проектом «Жидкий персонаж».
Все материалы вы традиционно можете скачать тут. В папку залиты файлы для обеих частей.
Порядок выполнения
Создадим новую панель со следующими параметрами:
Панель — отвечает за активную зону для нажатий. От её размеров зависит площадь, на которой будет работать стик.
Внутри панели создадим 2 Image согласно иерархии на скриншотах — Joy и Mushroom Joy — тело нашего стика, Mushroom — его грибок.
Их параметры:
Эти элементы являются вспомогательными для скрипта и потому, тип их привязки очень важен.
Создадим скрипт. Скрипт необходимо закинуть на панель. Его полный листинг выглядит так (если в таком формате совсем неудобно, пишите в комментах — перенаберу исходный код):
Разберём его подробнее
Для начала подключим пространство имён для обработки событий:
using UnityEngine.EventSystems;
За обработку нажатий отвечают методы OnPointerDown и OnPointerUp. Для их работы необходимы следующие интерфейсы: IpointerDownHandler и IpointerUpHandler.
Чтобы работать с информацией о конкретном нажатии (а в случае мультитача данных нажатий может быть несколько) объявляем поле private PointerEventData eventData;
При нажатии на экран вызывается OnPointerDown и складывает информацию о нажатии в eventData.
В дальнейшем это позволяет нам работать с eventData из метода Update ().
Для того, чтобы понимать, актульна ли информация о нажатии, введена булева переменная OnScreen. Если мы нажали на экран, то переменная принимает значение true, объект Joy становится в точку нажатия и объекты Joy и Mushroom становятся видимыми.
Метод OnPointerUp отключает видимость Joy и Mushroom и переводит переменную OnScreen в false.
Остальная обработка возникает в Update ().
Там мы выставляем Mushroom по глобальной точке нажатия и меряем её локальные координаты.
Принцип такой: нажали, грибок и джой выставились в току нажатия.
Передвинули палец/указатель — и грибок сместился относительно джоя. Это смещение мы и берём из локальных координат. Его и используем как результат.
Теперь, в любом скрипте, который используем методы типа GetAxis строку типа Input.GetAxis («Horizontal») меняем на CustomStick.horizontal
С вертикальной осью всё делаем по аналогии.
Для создания же обычных кнопок, допустим, кнопки прыжка, которая видима всегда и находится на одном месте, используем стандартный EventTrigger.
Приложенный ассет имеет полностью готовый и настроенный стик в виде префаба и сцены. Помните, что система эвентов не будет работать без данного объекта, который создаётся автоматически при создании Canvas через меню.
Хочется напомнить, все материалы рассчитаны на использование в составе проекта с главным героем — желе.
Перейдем ко второй части.
Использование своих типов эвентов через код
Откроем проект Goo (жидкий желеобразный персонаж), созданный ранее. Проект используется как пример, можно использовать любой другой.
Создадим новый скрипт. Его листинг:
Несмотря на то, что скрипт очень лёгкий, он может многое. Скрипт требует коллайдера в режиме триггера и реагирует на игрока.
Если мы выложим его на пустой объект на сцене, мы можем увидеть привычное окно системы эвентов.
Рассмотрим пару вариантов использования этого скрипта. Вариант первый — создание потайной двери-стены, открывающийся ключом. Для этого нам понадобится спрайт стены с обычным коллайдером и спрайт или модель ключа с коллайдером в режиме триггера.
Также можно добавить ещё один пустой объект и закинуть на него звук, создав тем самым AudioSource. Уберём у AudioSource галочку вопроизведения при старте и закинем в него ключ и стены.
Далее настроим сам ключ. В данной конфигурации ключ выключает стену, включает звук и выключает себя.
Это самый простой пример логики. Рассмотрим посложнее.
Создадим ловушку, в которую игрок может зайти, но как только будет пытаться выйти, перед ним будет закрываться дверь до тех пор, пока игрок не найдёт кнопку.
Создать её будет сложнее. Кратко, логику можно описать так: у нас есть стенка, которая включается, чтобы не дать игроку выйти. (изначально она выключена, чтобы игрок вошёл).
Стенку включает триггер, находящийся прямо возле неё. (Тоже изначально выключен)
По центру есть ещё один триггер, выключающий стенку и включающий триггер, включающий стенку.
Работает это так — игрок проходит сквозь выключенную стенку и сквозь выключенный триггер стенки, ничего не происходит. Заходит в триггер по центру и ловушка срабатывает. Теперь выйти нет никакой возможности.
Создадим кнопку. Для этого импортируем приложенное извображение и разрежем на 2 спрайта.
Расположим их в мире в одной точке, зелёный выключим и назовём его «Вкл», Красный назовём «Выкл».
Создадим ещё один пустой объект, закинем на него коллайдер, выставим коллайдеру режим триггера и расположим на кнопке. Настроим следующим образом:
Этот триггер выключает два других триггера ловушки, выключая всю логику ловушки и оставляя стенку выключенной, выключает красный спрайт и включает зелёный.
Таким образом, кнопка нажимается и ловушка отключается.
Сюда же можно добавить звук нажатия кнопки, закинув его на пустой объект или на сам спрайт зелёной кнопки и оставив галочку Play On Awake.
На этом этапе занятие можно считать завершённым.
Пишите комменты, делитесь полезными ссылками, как можно улучшить проект!
Пожалуйста, поддержите инициативу — нажимайте ↑ нравится и ➦ поделиться!