Поля UnityEvent
Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 12 из 50.
Свойство кнопки On Click () — это поле UnityEvent, и в своих скриптах ты тоже можешь создать такое поле. Публичное поле UnityEvent отображается в Inspector в виде такого же списка, а скрипт вызывает его с помощью Invoke(), не зная, что с ним связано. Этот обратный отсчёт обновляется раз в секунду:
using UnityEngine;
using UnityEngine.Events;
public class Countdown : MonoBehaviour
{
public int seconds = 3;
public UnityEvent<int> onTick;
public UnityEvent onFinished;
void Start()
{
InvokeRepeating("Tick", 1f, 1f);
}
void Tick()
{
seconds--;
onTick.Invoke(seconds);
if (seconds == 0)
{
CancelInvoke("Tick");
onFinished.Invoke();
}
}
}В Inspector событие On Finished () принимает строки, как у кнопки: одна строка запускает ракету, другая открывает ворота. На другом уровне используется тот же Countdown с другими строками, и никому не нужно писать новый скрипт. UnityEvent<int> передаёт значение. В выпадающем списке метод, принимающий int, отображается в разделе Dynamic int, и в эту строку передаётся значение, указанное в Invoke, — здесь это оставшееся количество секунд. Тот же метод в разделе Static Parameters вместо этого получает число, введённое в строку, также можно связать методы без параметров.
Unity создаёт поле UnityEvent при загрузке скрипта, поэтому onTick никогда не равно null и не нуждается в ?., а код может добавлять обработчики с помощью onTick.AddListener(ShowSeconds). Выбирай UnityEvent, если реакция различается от объекта к объекту и настраивается в Inspector тобой или дизайнером, который никогда не открывает скрипт. Выбирай событие C#, если обработчики задаются в коде: компилятор проверяет имена методов, поэтому их переименование приводит к ошибке сборки, а не оставляет незаметную строку <Missing>, и событие C# никогда не отображается в Inspector.
Задание
ЛегкоГонка из трех кругов вокруг острова. Стрелки управляют машиной (Car.cs), а сцена настроена так, как это сделал бы дизайнер в Inspector: список On Lap (Int32) объекта FinishLine вызывает LapBoard.ShowLaps (Dynamic int) для LapText и Crowd.Cheer для Crowd, а список On Race Over () вызывает LapBoard.ShowFinished и Car.Stop. Эти скрипты готовы, но к строкам пока нечего привязать, пока у FinishLine нет событий.
Напиши FinishLine.cs:
- Два поля UnityEvent:
onLap, которое передает int, иonRaceOver, которое ничего не передает. - Каждый раз, когда машина (с тегом
Player) пересекает линию, засчитывается круг: вызовиonLapс числом пройденных кругов (1, затем 2, затем 3). Пересечение линии чем-либо еще не засчитывается. - Когда число пройденных кругов достигнет
laps(3), вызовиonRaceOver. После этого пересечение линии ни к чему не приводит.
Нажми Play, проедь три круга вокруг острова, затем нажми Check.
Попробуйте сами
using UnityEngine;
public class FinishLine : MonoBehaviour
{
public int laps = 3;
void OnTriggerEnter(Collider other)
{
// машина пересекла финишную черту: пройден ещё один круг
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Архитектура игр в Unity
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыСовместная работа компонентовПовторение: модульная турель4Сериализованные данные
Сериализуемые классыСписки в InspectorПеречисления в InspectorПовторение: таблица лута2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействия5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиВолны как данныеПовторение: база предметов3События
События C# в UnityПодписка в OnEnableПоля UnityEventСобытия управляют интерфейсомПовторение: всплывающее окно достижения6Сохранение с помощью JSON
JsonUtilityСохранение игрыЗагрузка и значения по умолчаниюПовторение: слоты сохранения