Action и UnityAction
Автор: Дмитрий Прокопьев
Что такое Action и UnityAction?
Action
и UnityAction
это типы делегатов C#
, которые можно использовать в качестве типа события. Посмотрим на пример объявления события:
Объявление начинается с модификатора доступа. Так как события используются как средство передачи информации, это всегда
public
Ключевое слово
event
инкапсулирует событие, ограничивает количество доступных операций. Подробнее при это здесьТип делегата для этого события определяет поведение и передаваемые параметры события
Название события указывает, какую информацию оно передает. События всегда именуются в прошедшем времени, так как указывают на уже произошедшее.
Именование происходит в формате Существительное (какой объект изменился?) + Глагол (как объект изменился?). Например, MoneyAdded
, EnemyKilled
, DoorOpened
, PaymentReceived
и.т.д.
В чем разница между Action и UnityAction?
Эти типы отличаются несколькими параметрами:
Название
Action
находится вnamespace System
, аUnityAction
вnamespace UnityEngine
Action
может принимать от 0 до 16 параметров, аUnityAction
от 0 до 4.UnityAction
может в некоторых обстоятельствах работать некорректно, в отличие отAction
По указанным выше причинам рекомендуем использовать только Action
.
Как вызвать объявленное событие?
Нам известно, что событие передает информацию своим слушателям. Поэтому возникает вопрос, как запустить процесс передачи информации?
Мы добавили кошельку событие AmountChanged
, через которое он сообщает, что количество денег изменилось. Для начала подумаем, когда об этом нужно сообщать. Количество денег изменяется только в методах AddMoney
и TrySpendMoney
, поэтому вызывать событие будет логично именно в них. Сделать это можно c помощью метода Invoke
:
Однако есть одна проблема. Так как такое событие это делегат, то до первого подписанного метода оно не будет проинициализировано, а значит будет равно null
. Из за этого в момент вызова метода Invoke
мы получим NullReferenceException
. Решение простое, для этого нужно проверить событие на null
перед вызовом:
Правда каждый раз расписывать это заново неудобно, поэтому для этого есть краткая форма записи:
Как получать информацию из события?
Для этого другим компонентам потребуется подписаться на событие. Но как указать, что именно им делать при вызове события? Чтобы разобраться, попробуем привязать к кошельку компонент его отображения - WalletView
. Так он реализован сейчас:
Мы хотим, чтобы при срабатывании события AmountChanged
вызывался метод DisplayAmount
. Тогда каждый раз, когда количество денег в кошельке изменится, оно будет выведено на экран, чего мы и хотели.
Для этого мы можем подписаться на это событие методом DisplayAmount
. Сделать это нам поможет оператор +=
, вот так:
По техническим причинам необходимо всегда отписываться от событий, когда мы больше не хотим принимать информацию из них. Для этого есть оператор -=
:
Но когда это делать? Подписываться нужно с того момента, когда мы хотим начать слушать событие, а отписываться нужно, когда мы больше не хотим это делать. Но в этом случае мы всегда хотим получать информацию с кошелька!
Тогда будет удобно сделать это в методах OnEnable
и OnDisable
, так как они выполняются при включении и выключении объекта, включая начало и конец рантайма:
А так теперь выглядит сам кошелек:
И вот, это наконец-то работает! Теперь WalletView
реагирует на каждое изменение в Wallet
и отображает это на экране!
Last updated
Was this helpful?