- Event Dispatchers
- Примеры Event Dispatchers
- Пример из жизни
- Игровой пример
- Важные аспекты Event Dispatchers
- Работа с Event Dispatchers
- Создание диспетчера в Акторе-издателе
- Метод Call
- Метод Bind
- Метод Assign
- Методы Unbind и Unbind all
- Передача параметров через Event Dispatcher
- Event Dispatchers в Unreal Engine по умолчанию
- Actor
- Pawn
- Character
- Player Controller
- AI Controller
- Actor Component
- Scene Component
- Static Mesh
- Skeletal Mesh
- Audio
- Projectile Movement
- Interp To Movement
- Pawn Sensing
- Практический урок в Unreal Engine: придаём импульс объектам при приземлении персонажа при помощи Event Dispatcher
- Вызов Event Dispatcher в персонаже игрока. Метод Call
- Создание Актора BP_Actor
- Получаем ссылку на объект персонажа игрока
- Событие импульса
- При пересечении коллизии компонента Box подписываемся на Event Dispatcher. Метод Bind
- При выходе из коллизии компонента Box отписываемся от Event Dispatcher. Метод Unbind
- Встроенный диспетчер Landed Delegate
Приветствую, друзья, с Вами Будуев Антон. В данной статье мы разберём Event Dispatchers в Unreal Engine (UE5, UE4) или, как их ещё называют, диспетчеры событий или Delegates (делегаты).
Вскоре выйдет моя бесплатная книга по Blueprints для Unreal Engine в PDF формате. Как она выйдет, рекомендую её скачать, чтобы Вы детально изучили блюпринты Анрил Энджин.
Event Dispatchers
Event Dispatchers (диспетчеры событий) в Unreal Engine — это механизм для организации взаимодействия между различными объектами в игре, где один объект может «оповестить» множество других объектов о каком-либо действии или состоянии, запустив в этих множественных объектах определённые события или функции и передав им информацию через параметры.

Проще говоря, Event Dispatcher — это инструмент, который позволяет какому-либо Актору при возникновении условий отправить любому количеству подписчиков (другим Акторам) информацию и некий «сигнал», запускающий у подписчиков определённые события. А другие Акторы могут «подписаться» на этот сигнал и информацию, чтобы выполнять нужные им действия при их получении.
Актор, который отправляет «сообщение», обычно называется Publisher (издатель), а Актор, подписавшийся на это «сообщение» — Subscriber (подписчик) или Observer (наблюдатель).
Чтобы организовать этот процесс, в Акторе-издателе необходимо создать Event Dispatcher. Тогда Актор-подписчик сможет подписаться на этот диспетчер, подписав на него специально созданное для этого событие или функцию. Подписка означает, что событие или функция будут добавлены в специальный список диспетчера. В нужный момент времени диспетчер будет вызывать все события и функции из этого списка, передавая необходимую информацию через параметры.
Иначе говоря, Event Dispatcher, расположенный в Акторе-издателе, в заданное время инициирует (запускает на выполнение) определённые события или функции в Акторах-подписчиках, которые были подписаны на него. Одновременно с этим он передает необходимую информацию от издателя к подписчику через параметры запускаемых событий. Таким образом, осуществляется взаимодействие между Актором-издателем и Актором-подписчиком.
Примеры Event Dispatchers
Пример из жизни
Чтобы лучше понять, как работает Event Dispatcher, давайте рассмотрим простой пример из жизни. Конечно, это лишь условный и очень приближённый пример. Если рассматривать детали, то они, естественно, отличаются от реальных процессов, которые происходят в диспетчере событий. Но если взглянуть на общую картину, то это будет очень похоже на то, как это работает в действительности.
Итак, все знают мессенджер Telegram. У меня в этом мессенджере есть группа «Unreal Engine — это просто». В этой группе я регулярно делюсь постами с информацией о новых статьях на нашем сайте. С точки зрения Event Dispatcher, я выступаю в роли издателя, который отправляет сообщения при наступлении определённых условий (написание статьи на сайте).
Любой пользователь Telegram может присоединиться к нашей группе, подписавшись на мои сообщения. Когда я буду публиковать что-то новое, все подписчики получат уведомление и смогут либо просто прочитать сообщение, либо прочитать сообщение и перейти по ссылке на сайт, чтобы ознакомиться со статьей.
С точки зрения Event Dispatcher, такие пользователи будут являться подписчиками, которым приходит уведомление о наступившем у меня событии (написание статьи). Далее каждый подписчик это событие обрабатывает по-своему. Кто-то игнорирует, кто-то сообщение просто читает, а кто-то не только читает, но и переходит по ссылке из сообщения на сайт.
При этом я, как издатель, ничего не знаю про своих подписчиков и не знаю, как они обрабатывают мои сообщения. Но вот подписчики меня как издателя знают, и с точки зрения Event Dispatcher это важно.
Ну а сам Телеграмм — это и есть тот самый Event Dispatcher, который позволяет мне, как издателю, отправлять сообщения с информацией, а подписчикам — подписаться на меня, получать эти сообщения и реагировать на них.
Игровой пример
В качестве игрового примера использования Event Dispatchers в Unreal Engine рассмотрим оповещение разных игровых объектов об изменении состояния здоровья игрока и одновременный запуск в этих объектах соответствующих логических цепочек.
Когда здоровье игрока уменьшается или увеличивается, в игре может происходить множество событий, которые затрагивают самые разные объекты.
Ну, например:
- на экране можно отобразить обновлённую полоску здоровья персонажа;
- при предельно низком здоровье, экран игрока может потускнеть;
- при предельно низком здоровье, противники могут еще больше активизироваться и начать плотнее нападать на игрока.
Все эти события, такие как изменение полоски здоровья, затухание экрана или активизация нападения врагов, должны происходить в отдельных Акторах, которые не связаны с Актором персонажа игрока. При этом все эти действия зависят от изменения здоровья персонажа, будь то его снижение или увеличение.
Чтобы передавать информацию об изменении здоровья различным Акторам, в Акторе игрока необходимо создать Event Dispatcher.
Затем тем Акторам, которые зависят от состояния здоровья персонажа, нужно подписаться на этот Event Dispatcher. Когда у персонажа игрока произойдёт изменение здоровья, у всех участников, подписавшихся на этот диспетчер, будут запущены соответствующие события и функции, а также передана информация о текущем уровне здоровья.
Таким образом, если персонаж игрока получит урон, на экране отобразится уменьшающаяся полоска здоровья, сам экран станет более тусклым, а враги начнут нападать ещё активнее. Все эти изменения будут происходить в различных Акторах-подписчиках и управляться одним диспетчером событий из Актора-издателя.
Важные аспекты Event Dispatchers
- Издатель ничего не знает про своих подписчиков — Актор, который при помощи Event Dispatcher издаёт «сообщение» и запускает события у подписчиков, абсолютно ничего не знает о том, кто подписан на его «сообщение» и сколько всего у него подписчиков. Ему это не важно. Издателю просто нужно у себя создать диспетчер и вовремя вызвать его.
- Подписчики обязаны знать про издателя — любому Актору, которому необходимо подписаться на издателя, обязательно нужно знать о нём, иначе говоря, он должен иметь ссылку на этого Актора-издателя, из которой открывается доступ к специальной ноде Bind, позволяющей привязать событие или функцию на этот диспетчер.
- На Event Dispatcher можно как подписаться, так и отписаться — Акторы-подписчики могут как подписаться на диспетчер Актора-издателя, так и в любой момент отписаться, чтобы больше не получать никаких «сообщений» от издателя.
- Event Dispatcher формирует список функций и событий, которые затем вызывает — подписка на Event Dispatcher на самом деле означает, что определённое событие или функция Актора-подписчика будет добавлена в список вызова диспетчера. Затем в нужный момент диспетчер произведёт вызов всех функций и событий из этого списка, передав при этом через параметры необходимую информацию.
- Издатель через Event Dispatcher может передавать подписчику информацию — Event Dispatcher может запускать события подписчиков как без параметров, просто запуская логическую цепочку, так и с дополнительными параметрами, передающими подписчикам информацию, которую они могут использовать в своей логике.
- Параметры диспетчера и вызываемых событий или функций должны совпадать — при передаче информации от Актора-издателя к Актору-подписчику через Event Dispatcher параметры диспетчера и подписываемых событий (функций) Акторов-подписчиков обязательно должны совпадать (точнее должны совпадать типы параметров и их последовательность).
Работа с Event Dispatchers
Создание диспетчера в Акторе-издателе
Диспетчеры событий в Акторе-издателе создаются в редакторе Blueprint во вкладке My Blueprint по нажатию на кнопку «+» напротив пункта Event Dispatcher. После создания данному диспетчеру можно задать любое осмысленное пользовательское имя.

Метод Call
Для того чтобы в нужный момент времени передать от издателя к подписчикам информацию и запустить логику, в Акторе-издателе необходимо вызвать созданный диспетчер событий, запустив в Event Graph издателя специализированную ноду Call (вызов). Получить её можно, перетащив левой клавишей мыши созданный Event Dispatcher на поле Event Graph и при отжатии мыши выбрав пункт Call (вызов диспетчера событий).

После этого в Event Graph будет создана функция Call, которую необходимо разместить в том месте логики Актора-издателя, где требуется оповестить всех подписчиков о произошедшем событии.

Именно вызов данной ноды и приводит в Акторах-подписчиках к срабатыванию всех событий и функций, привязанных к диспетчеру событий издателя. Если функцию Call вызвать несколько раз, то срабатывание привязанных событий и функций в Акторах-подписчиках аналогично также будет производится несколько раз.
Метод Bind
Вызов Event Dispatcher не будет иметь эффекта, если к нему не привязаны события. У каждого диспетчера есть свой список связанных с ним событий или функций Акторов-подписчиков. Чтобы их добавить в этот список, в Акторе-подписчике необходимо вызвать метод Bind для нужного диспетчера событий.
Для этого, как я уже упомянул выше, обязательно требуется ссылка на объект Актора-издателя, из которой можно получить метод Bind диспетчера этого издателя, указав слово «Bind» и имя самого диспетчера в поиске нод данной ссылки.
Ссылку на объект издателя можно получить любыми доступными способами, который предоставляет Unreal Engine. Самым наилучшим способом будет использование интерфейсов, но можно воспользоваться и приведением типов (Cast), как на примере ниже, где через Cast мы получаем ссылку на персонажа игрока.

После выбора метода Bind будет создана соответствующая нода, позволяющая привязать пользовательское событие (Custom Event) или пользовательскую функцию Актора-подписчика. Привязка событий возможна двумя способами (1 и 2), а функций только одним (способ 2):
- Прямая привязка через Delegate — пользовательское событие (Custom Event) может быть привязано к Bind через прямую связь между красными Pin-квадратами Event Delegate (делегат).

- Привязка через ноду Create Event — пользовательское событие (Custom Event) или пользовательская функция могут быть привязаны к Bind через ноду Create Event, которую можно добавить, введя название «Create Event» в меню красного Pin-квадрата Event Delegate в Bind. Далее внутри ноды Create Event в поле Select Function можно выбрать пользовательское событие или функцию по названию.

Сам же процесс привязки к Event Dispatcher в Акторе-подписчике делают в том месте кода, где нужно начать отслеживать определённое состояние у Актора-издателя. Зачастую это делают в самом начале работы Актора-подписчика, на событии Event Begin Play.
Внимание! Привязка событий и функций к ноде Bind возможна только лишь в том случае, если их параметры совпадают с параметрами самого диспетчера. Если у диспетчера нет вообще параметров, то и у привязываемых событий и функций также не должно быть параметров. Иначе говоря, сигнатура у них должна быть абсолютно одинаковой.
* Как добавить параметры к диспетчеру мы разберём ниже в статье.
Метод Assign
Для того чтобы при подписке не создавать отдельно ноду Bind и отдельно пользовательское событие (Custom Event) для привязки к Bind, можно воспользоваться методом Assign, который полностью похож на метод Bind, но, кроме того, в автоматическом режиме сразу создаёт привязанное к ноде Bind событие. Что удобно и уменьшает количество операций.

Методы Unbind и Unbind all
Когда созданная привязка уже не требуется, её следует отключать. Делается это методом Unbind, который добавляется на график точно так же, как и Bind. После добавления на график в ноде Unbind необходимо указать событие или функцию для отвязки.
Саму ноду Unbind размещают в том месте кода, где необходимо произвести отвязку от диспетчера.
Также можно воспользоваться методом Unbind all, который отвяжет абсолютно все события и функции от Event Dispatcher. Поэтому использовать данный метод нужно осторожно и внимательно, так как отвязка произойдёт не только текущего Актора-подписчика, а вообще всех подписчиков.

Передача параметров через Event Dispatcher
Как я уже упоминал выше, Event Dispatcher при вызове событий и функций из своего списка может передавать им информацию через свои параметры. При этом сигнатура (тип и расположение параметров) у диспетчера и вызываемых событий (функций) обязательно должна совпадать.
Добавление параметров в Event Dispatcher производится в его свойствах. Для этого необходимо выделить название диспетчера, перейти во вкладку Details, в меню Inputs и нажать на кнопку «+». После откроется возможность задать имя параметру и его тип. Также, если параметров много, и такая структура параметров уже использовалась в каких-либо других функциях, для удобства и экономии времени в этом же меню через опцию Copy Signature from имеется возможность скопировать сигнатуру (типы и расположение параметров) из других функций.

В этом же меню Inputs после компиляции данным параметрам можно задать значение по умолчанию. Либо передать значения из других функций непосредственно в саму ноду Call.

Event Dispatchers в Unreal Engine по умолчанию
В Unreal Engine во многих Blueprint-классах уже по умолчанию встроено множество готовых Event Dispatchers, на которые можно подписаться. В данном разделе статьи кратко разбёрем все стандартные дефолтные диспетчеры для каждого из классов.
Actor
Диспетчеры класса Actor находятся во вкладке Details в меню Events.

- On Take Any Damage — событие вызывается, когда Актор получает любой урон.
- On Take Point Damage — событие вызывается, когда Актор получает точечный урон.
- On Take Radial Damage — событие вызывается, когда Актор получает радиальный урон.
- On Actor Begin Overlap — событие вызывается, когда Актор начинает перекрывать (пересекать) другой объект с включенной коллизией.
- On Actor End Overlap — событие вызывается, когда Актор перестаёт перекрывать (пересекать) другой объект с включенной коллизией.
- On Begin Cursor Over — событие вызывается, когда курсор мыши начинает наводиться на текущий Актор.
- On End Cursor Over — событие вызывается, когда курсор мыши перестаёт наводиться на текущий Актор.
- On Clicked — событие вызывается, когда пользователь нажимает на Актор мышью.
- On Released — событие вызывается, когда пользователь отпускает кнопку мыши после нажатия на Актор.
- On Input Touch Begin — событие вызывается, когда пользователь начинает касаться Актора на сенсорном устройстве.
- On Input Touch End — событие вызывается, когда пользователь перестаёт касаться Актора на сенсорном устройстве.
- On Input Touch Enter — событие вызывается, когда пользователь начинает касаться Актора, проводя пальцем по сенсорному экрану.
- On Input Touch Leave — событие вызывается, когда пользователь прекращает касаться Актора, проводя пальцем по сенсорному экрану.
- On Actor Hit — событие вызывается, когда Актор сталкивается с другим объектом.
- On Destroyed — событие вызывается, когда Актор был явно уничтожен.
- On End Play — событие вызывается при удалении или перемещении Актора за пределы уровня.
Pawn
Диспетчеры класса Pawn находятся во вкладке Details в меню Events. К ним относятся все диспетчеры класса Actor, а также нижеследующие.

- Receive Controller Changed Delegate — событие вызывается на сервере и клиенте-владельце после смены контроллера у Pawn.
- Receive Restarted Delegate — событие вызывается на сервере или клиенте-владельце в момент перезапуска текущего Pawn (обычно при изменении владения).
Character
Диспетчеры класса Character находятся во вкладке Details в меню Events. К ним относятся все диспетчеры класса Pawn, а также нижеследующие.

- On Reached Jump Apex — событие вызывается, когда персонаж достигает наивысшей точки (Apex, пика) своего прыжка.
- Landed Delegate — событие вызывается в момент приземления персонажа в результате падения (прыжка).
- Movement Mode Changed Delegate — событие вызывается, когда изменяется режим движения (Movement Mode) объекта персонажа.
- On Character Movement Updated — событие вызывается по окончании обновления перемещения компонента Character Movement.
Player Controller
Диспетчеры класса Player Controller находятся во вкладке Details в меню Events. К ним относятся все диспетчеры класса Actor, а также нижеследующие.

- On Instigated Any Damage — событие вызывается, когда контроллер наносит какой-либо урон другому Актору.
- On Possesses Pawn Changed — событие вызывается на сервере и клиенте, когда у контроллера происходит смена принадлежащего ему Pawn.
AI Controller
Диспетчеры класса AI Controller находятся во вкладке Details в меню Events. К ним относятся все диспетчеры класса Player Controller, а также нижеследующий.

- Move Completed — событие вызывается, когда управляемый объект завершает своё перемещение к заданной цели.
Actor Component
Диспетчеры компонента Actor Component находятся во вкладке Details в меню Events.

- On Component Activated — событие вызывается, когда текущий компонент активируется.
- On Component Deactivated — событие вызывается, когда текущий компонент деактивируется.
Scene Component
Диспетчеры компонента Scene Component находятся во вкладке Details в меню Events, или же в контекстном меню самого компонента (в подменю Add Event). К ним относятся все диспетчеры компонента Actor Component, а также нижеследующий.

- Physics Volume Changed — событие вызывается, когда компонент входит или выходит из Physics Volume, или когда изменяются свойства Physics Volume.
Static Mesh
Диспетчеры компонента Static Mesh Component находятся во вкладке Details в меню Events, или же в контекстном меню самого компонента (в подменю Add Event). К ним относятся все диспетчеры компонента Scene Component, а также нижеследующие.

- On Component Hit — событие вызывается, когда компонент сталкивается с другим объектом.
- On Component Begin Overlap — событие вызывается, когда компонент начинает перекрывать (пересекать) другой объект с включенной коллизией.
- On Component End Overlap — событие вызывается, когда компонент перестаёт перекрывать (пересекать) другой объект с включенной коллизией.
- On Component Wake — событие вызывается, когда компонент, который симулирует физику, «просыпается» из состояния покоя.
- On Component Sleep — событие вызывается, когда компонент, который симулирует физику, переходит в состояние покоя (засыпает).
- On Component Physics State Changed — событие вызывается, когда у компонента изменяется физическое состояние.
- On Begin Cursor Over — событие вызывается, когда курсор мыши начинает наводиться на текущий компонент.
- On End Cursor Over — событие вызывается, когда курсор мыши перестаёт наводиться на текущий компонент.
- On Clicked — событие вызывается, когда пользователь нажимает на компонент мышью.
- On Released — событие вызывается, когда пользователь отпускает кнопку мыши после нажатия на компонент.
- On Input Touch Begin — событие вызывается, когда пользователь начинает касаться компонента на сенсорном устройстве.
- On Input Touch End — событие вызывается, когда пользователь перестаёт касаться компонента на сенсорном устройстве.
- On Input Touch Enter — событие вызывается, когда пользователь начинает касаться компонента, проводя пальцем по сенсорному экрану.
- On Input Touch Leave — событие вызывается, когда пользователь прекращает касаться компонента, проводя пальцем по сенсорному экрану.
Skeletal Mesh
Диспетчеры компонента Skeletal Mesh Component находятся во вкладке Details в меню Events, или же в контекстном меню самого компонента (в подменю Add Event). К ним относятся все диспетчеры компонента Static Mesh Component, а также нижеследующие.

- On Constraint Broken — событие вызывается, когда происходит нарушение ограничений (Constraint) в Skeletal Mesh.
- On Plastic Deformation — событие вызывается при пластической деформации Skeletal Mesh.
- On Anim Initialized — событие вызывается при инициализации экземпляра анимации текущего компонента скелетного Меша.
Audio
Диспетчеры компонента Audio Component находятся во вкладке Details в меню Events, или же в контекстном меню самого компонента (в подменю Add Event). К ним относятся все диспетчеры компонента Scene Component, а также нижеследующие.

- On Audio Play State Changed — событие вызывается при изменении состояния воспроизведения и возвращает текущее изменённое состояние.
- On Audio Virtualization Changed — событие вызывается при изменении состояния виртуализации.
- On Audio Finished — событие вызывается при окончании воспроизведения звука.
- On Audio Playback Percent — событие вызывается при воспроизведении звука в аудиокомпоненте, чтобы иметь возможность выполнять действия в зависимости от процента воспроизведения. Рассчитывается как количество воспроизведённых сэмплов, делённое на общее количество сэмплов, с учётом высоты тона. В настоящее время реализовано не на всех платформах.
- On Audio Single Envelope Value — событие вызывается непрерывно во время воспроизведения звука, предоставляя текущее значение огибающей (Envelope) воспроизводимого звука. Огибающая представляет собой динамическое значение, которое отражает амплитуду или «громкость» звука в реальном времени. Это событие используется для синхронизации игровой логики с изменениями уровня громкости звука.
- On Audio Multi Envelope Value — событие вызывается непрерывно во время воспроизведения звука для предоставления текущих значений нескольких огибающих (Envelope) аудиосигнала.
Projectile Movement
Диспетчеры компонента Projectile Movement находятся во вкладке Details в меню Events, или же в контекстном меню самого компонента (в подменю Add Event). К ним относятся все диспетчеры компонента Actor Component, а также нижеследующие.

- On Projectile Bounce — событие вызывается, когда снаряд (Projectile) сталкивается с поверхностью и отскакивает от неё. Это событие позволяет реагировать на момент отскока и выполнять логику, связанную с этим физическим взаимодействием.
- On Projectile Stop — событие вызывается, когда снаряд (Projectile) остановился.
Interp To Movement
Диспетчеры компонента Interp To Movement находятся во вкладке Details в меню Events, или же в контекстном меню самого компонента (в подменю Add Event). К ним относятся все диспетчеры компонента Actor Component, а также нижеследующие.

- On Interp to Reverse — событие вызывается, когда направление интерполяции движения меняется на противоположное.
- On Interp to Stop — событие вызывается, когда интерполяционное движение останавливается.
- On Wait Begin Delegate — событие вызывается, когда объект завершает интерполяцию к целевой точке и переходит в состояние ожидания (Wait State). Это событие позволяет реагировать на момент начала паузы перед следующим этапом интерполяционного движения.
- On Wait End Delegate — событие вызывается, когда объект завершил состояние ожидания (Wait State) и продолжил движение. Это событие позволяет реагировать на момент окончания паузы и начала нового этапа интерполяционного движения.
- On Reset Delegate — событие вызывается, когда интерполяционное движение объекта сбрасывается (Reset) в исходное состояние. Это событие позволяет реагировать на момент сброса движения, например, при отмене текущего перемещения или возврате объекта в начальную позицию.
Pawn Sensing
Диспетчеры компонента Pawn Sensing находятся во вкладке Details в меню Events, или же в контекстном меню самого компонента (в подменю Add Event). К ним относятся все диспетчеры компонента Actor Component, а также нижеследующие.

- On See Pawn — событие вызывается, когда компонент обнаруживает объект Pawn в пределах своей зоны видимости.
- On Hear Noise — событие вызывается, когда компонент слышит шум, генерируемый компонентом Pawn Noise Emitter.
Практический урок в Unreal Engine: придаём импульс объектам при приземлении персонажа при помощи Event Dispatcher
Задача: при помощи использования диспетчера событий Event Dispatcher придать импульс объектам при приземлении персонажа игрока.
В уроке будем использовать стандартный шаблон проекта игры от третьего лица в Unreal Engine (UE5).
Для того чтобы придать импульс объектам при приземлении персонажа, необходимо создать систему издатель-подписчик или, как её ещё называют, Observer (наблюдатель).
Объекты, которым необходимо добавить импульс, будут подписчиками или наблюдателями. А персонаж игрока — издателем. В нём мы разместим созданный нами диспетчер событий, который и будет запускать соответствующие события с импульсами в объектах-подписчиках, когда персонаж будет приземляться.
Но, исходя из информации в статье выше, на самом деле в классе Character уже есть встроенный диспетчер, реагирующий на приземление персонажа, — диспетчер Landed Delegate. В целях обучения для начала мы всё же создадим свой пользовательский диспетчер, а затем уже попробуем встроенный.
Вызов Event Dispatcher в персонаже игрока. Метод Call
- Откроем блюпринт персонажа игрока BP_ThirdPersonCharacter по пути /All/Game/ThirdPerson/Blueprints.
- Через меню Functions / Override вкладки My Blueprint добавим в Event Graph событие Event On Landed, срабатывающее в классе Character по приземлению персонажа во время падения (прыжка).
- Создадим свой пользовательский диспетчер событий EventDispatcher_OnLanded и добавим ему параметр Impuls типа float со значением по умолчанию 300. Эту информацию мы будем транслировать в объекты-подписчики.
- Вызовем у нашего диспетчера EventDispatcher_OnLanded метод Call и разместим его в логической цепочке события Event On Landed, которое мы добавляли в пункте 2.
Таким образом, когда персонаж игрока будет приземляться на поверхность, в его коде будет срабатывать событие Event On Landed, запускающее наш диспетчер EventDispatcher_OnLanded. Который, в свою очередь, будет запускать соответствующие события во всех других объектах-подписчиках (импульсы для этих объектов).
Скриншот
Код на BlueprintUE

Создание Актора BP_Actor
Теперь перейдём к созданию объектов, реагирующих на приземление персонажа игрока.
- Создадим блюпринт BP_Actor класса Actor.
- Внутри BP_Actor в качестве визуализации объекта добавим компонент Cube.
- Для того чтобы мы смогли добавить объекту куба импульс, включим для компонента Cube симуляцию физики через настройки Details/Physics/Simulate Physics = True.
- Добавим Актору коллизию с помощью компонента Box Collision, чтобы объект реагировал на приземление персонажа игрока только тогда, когда персонаж находится в непосредственной близости от объекта.
- Увеличим Box Collision через настройки Details/Shape/Box Extent.
- Для удобства тестирования игровой механики выключим у Box Collision параметр Details/Rendering/Hidden in Game = False. Таким образом, коробка коллизии будет отображаться в процессе игры.

Получаем ссылку на объект персонажа игрока
Перейдем в BP_Actor во вкладку Event Graph и получим ссылку на персонажа игрока, используя Cast. * Хотя, обращаю внимание, лучше использовать интерфейсы, но для упрощения урока мы будем использовать именно Cast.
По событию Event Begin Play с помощью Cast приведём объект типа Character, который вернёт функция Get Player Character, к типу BP_ThirdPersonCharacter и сохраним ссылку на объект персонажа игрока в переменную As_BP_ThirdPersonCharacter.
Таким образом, в самом начале работы данного Актора в игре мы внутри него получим ссылку на персонажа игрока и затем в нужном месте логики сможем как подписаться, так и отписаться от диспетчера, размещённого в этом игроке.
Скриншот
Код на BlueprintUE

Событие импульса
- Для добавления импульса нашему объекту, создадим Custom Event (пользовательское событие) — Person On Landed. Именно данное событие мы и будем подписывать на диспетчер EventDispatcher_OnLanded.
- Так как наш диспетчер событий содержит float-параметр, то подписываемое событие также должно содержать такой же параметр. Соответственно, добавим событию Person On Landed параметр Impuls типа float. Именно в этот параметр диспетчер и будет передавать информацию при вызове нашего события.
- Далее по вызову события Person On Landed добавим кубу импульс функцией Add Impulse.
- В параметр Target функции Add Impulse подадим объект куба, который возвратит функция Get Cube.
- Разделим правой клавишей мыши через опцию Split Struct Pin параметр Impulse функции Add Impulse на три раздельных float-параметра.
- Так как импульс нам нужно придать только по оси Z (вертикально вверх), то в функцию Add Impulse передадим значение импульса из события Person On Landed только в параметр Impulse Z.
- Ну и последнее, включим у функции Add Impulse параметр Vel Change = True, чтобы импульс объекту задавался через изменение его скорости.
Скриншот
Код на BlueprintUE

При пересечении коллизии компонента Box подписываемся на Event Dispatcher. Метод Bind
Чтобы не регистрировать события приземления персонажа игрока всё время, а только в непосредственной близости от BP_Actor, подписываться/отписываться от его сигналов мы будем по пересечению коллизии компонента Box Collision. Итак, подпишемся на сигналы диспетчера при начале пересечения этой коллизии.
- Вызовем у компонента Box Collision событие On Component Begin Overlap, которое, кстати, также является стандартным диспетчером компонента Box Collision, вызываемым при начале пересечения коллизии.
- Добавим из ссылки на персонажа игрока As_BP_ThirdPersonCharacter метод Bind нашего диспетчера событий EventDispatcher_OnLanded. И подключим добавленную ноду к событию On Component Begin Overlap. Но перед этим предварительно спросим, является ли пересекающий Актор персонажем игрока.
- Привяжем наше пользовательское событие Person On Landed, придающее импульс объекту, к методу Bind функцией Create Event.
Таким образом, при пересечении игроком коллизии BP_Actor мы начнём отслеживать диспетчер и ждать наступления события приземления персонажа. Как оно произойдет, сработает наше пользовательское событие Person On Landed, и куб немного подпрыгнет вверх.
Скриншот
Код на BlueprintUE

При выходе из коллизии компонента Box отписываемся от Event Dispatcher. Метод Unbind
Осталось немного — отключить подписку, как только персонаж игрока выйдет из коллизии Box Collision. Код в данном случае будет полностью аналогичным коду подписки, просто вместо метода Bind мы будем использовать метод Unbind, отписывающий событие Person On Landed от диспетчера EventDispatcher_OnLanded.
Скриншот
Код на BlueprintUE

Встроенный диспетчер Landed Delegate
Как я уже писал в самом начале практики, мы могли вообще не создавать собственный диспетчер, так как в классе Character уже имеется аналогичный встроенный диспетчер Landed Delegate, срабатывающий при приземлении персонажа Character.
При применении встроенного диспетчера код в разы становится проще.
- В самом персонаже игрока BP_ThirdPersonCharacter нам вообще ничего не нужно делать. То есть тот код, который мы в нём размещали, можно полностью удалить.
- При применении встроенного диспетчера нам также не нужен Cast на BP_ThirdPersonCharacter. Так как встроенный диспетчер доступен на уровне класса Character, объект которого нам возвращает функция Get Player Character. А отсутствие Cast — это оптимизация кода.
- Единственное, при использовании встроенных диспетчером у нас пропадает возможность передавать параметры, которые мы захотим. Соответственно, от параметра типа float, через который мы передавали значение импульса, нам придётся отказаться. И это значение нужно будет указать в функции Add Impulse напрямую.
- Так как встроенный диспетчер имеет собственные параметры, то нам необходимо изменить подписываемую функцию Person On Landed. Прошлый float-параметр необходимо удалить, а вместо него разместить параметр типа Hit Result Structure, который в целом нам не нужен, но необходим из-за его наличия в диспетчере.
- Ну и последнее, методы Bind и Unbind также нужно заменить на новые, относящиеся к встроенному диспетчеру Landed Delegate.
Скриншот
Код на BlueprintUE

Совет. Вскоре выйдет моя бесплатная книга по Blueprints для Unreal Engine в PDF формате. Как она выйдет, рекомендую её скачать, чтобы Вы детально изучили блюпринты Анрил Энджин.