Menu
CoddyTech

Поля 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.

challenge icon

Задание

Легко

Гонка из трех кругов вокруг острова. Стрелки управляют машиной (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)
    {
        // машина пересекла финишную черту: пройден ещё один круг
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Архитектура игр в Unity