- Timer (таймеры) в Unreal Engine Blueprint
- Blueprint функции для работы с таймером
- Установка таймеров
- Очистка и инвалидация таймеров
- Проверка наличия таймера
- Получение времени таймера (прошедшее и оставшееся)
- Состояние таймера: активность и пауза
- Приостановка и возобновление таймера
- Timer Manager (менеджер таймеров)
- Почему таймер, а не Event Tick или Delay
Timer (таймеры) в Unreal Engine Blueprint
В данной статье мы рассмотрим Timer (таймеры) в Unreal Engine Blueprint. Вообще, таймеры очень часто являются более эффективной заменой использования Event Tick или Delay, поэтому в статье будем рассматривать таймеры в сравнении с этими обоими инструментами.
Также рекомендую скачать мою бесплатную книгу по Blueprint для Unreal Engine.
Основная цель книги — дать общий, целостный и понятный обзор системы Blueprint. Книга предлагает взгляд с высоты «птичьего полёта» — ясную и чёткую карту игрового мира Unreal Engine, которая поможет увидеть ключевые взаимосвязи и понять, как устроена система визуального скриптинга.
Зарегистрироваться в ЛК и скачать книгу [Blueprints. Взгляд с высоты «птичьего полёта»]
Как мы знаем, Event Tick выполняется каждый кадр игры и используется для выполнения логики, которая должна рассчитываться постоянно. Например, плавное движение объектов, изменение их положения, повороты и другие процессы, где важна плавность, непрерывность обновления и постоянство процесса.
При этом довольно распространено мнение, что Event Tick — это «зло», и вместо него всегда необходимо использовать таймеры. На практике это не совсем так. В Unreal Engine нет «плохих» инструментов — если инструмент существует, значит он для чего-то предназначен. Важно не избегать его, а уметь правильно применять в нужный момент.
Ну, во-первых, используя Event Tick, можно контролировать его производительность, например, включать и выключать его при необходимости или же уменьшать частоту его вызова для соблюдения производительности всей системы.
Во-вторых, по своему прямому назначению Event Tick используется, например, для расчёта движения, позиции и поворота объектов — то есть того, что должно обновляться каждый кадр и постоянно. Если такие вычисления выполнять реже, изображение просто будет выглядеть дёрганым.
Во всех остальных случаях действительно лучше использовать таймеры. Теперь разберёмся, что это вообще такое и, главное, почему во всех остальных случаях лучше использовать их.
Итак, Timer (таймер) в Unreal Engine — это механизм для планирования вызова функций или событий через заданные интервалы времени или с определенной задержкой. Они позволяют выполнять действия с установленной периодичностью или после паузы без необходимости использовать Event Tick или Delay.
В Blueprint таймеры создаются в Event Graph с помощью следующих узлов:
- Set Timer by Event — таймер для вызова события.

- Set Timer by Function Name — таймер для вызова функции.

При использовании таймера для вызова функции достаточно в параметре «Function Name» указать имя существующей функции текущего Blueprint-класса. При срабатывании таймера будет вызвана именно эта функция. Важно, чтобы имя было указано точно и функция действительно существовала в текущем классе.
При использовании таймера для вызова события необходимо передать в него пользовательское событие (Custom Event), которое будет вызвано при срабатывании таймера. Это событие можно создать заранее в Event Graph и подключить к таймеру через Event Delegate (красные пины), либо создать его прямо из узла таймера — протянув провод от Delegate и выбрав Add Custom Event.

После подключения таймера к логике (например, от Begin Play или другого события) и указания функции или события для вызова, по истечении времени, заданного в параметре Time, автоматически будет выполнен соответствующий вызов.

Таким образом, таймер можно использовать как задержку на величину указанного времени в параметре Time — аналогично узлу Delay, но с гораздо большей гибкостью.
Также таймер можно использовать как цикл. Для этого необходимо включить параметр Looping, и тогда указанный вызов будет повторяться через заданный интервал времени, опять же указанный в параметре Time. В этом случае таймер с установленным временем повтора вызова, например, где параметр Time = 0.05, часто выступает альтернативой Event Tick, но более оптимизированной.
Как мы уже рассмотрели, основной параметр таймера — это Time — интервал времени до срабатывания, если таймер используется просто как задержка. Или же интервал между повторными вызовами, в случае, если таймер используется для циклического вызова событий или функций.
Дополнительные параметры таймеров:
- Looping — повторять ли таймер в циклическом режиме
- Max Once Per Frame — ограничивает количество срабатываний за кадр (полезно при маленьких значениях Time)
- Initial Start Delay — задержка перед первым запуском
- Initial Start Delay Variance — случайное отклонение начальной задержки.
В качестве возвращаемого значения (Return Value) таймеры выдают Timer Handle — уникальный идентификатор таймера в системе.
Если в дальнейшем требуется управлять таймером (например, остановить его, поставить на паузу или проверить его состояние), необходимо сохранить этот Handle в переменную. Это можно сделать, вытянув провод из Return Value и выбрав Promote to Variable.

После этого, используя сохранённый Handle, можно управлять таймером с помощью специальных функций. Например, для данного хендла можно вызвать узел Clear and Invalidate Timer by Handle, который очистит, или, иначе говоря, удалит данный таймер из системы. Таким образом, данный таймер не будет вызван вообще, а значит, и привязанная к таймеру функция или событие не сработают.

Когда это может потребоваться, ну, например, таймер можно включить, когда персонаж входит в огонь, и, пока он там находится, циклично по таймеру наносить персонажу урон. Затем, когда персонаж выйдет из огня, данный таймер по сохраненному хендлу можно удалить. А это значит, что таймер более не будет вызываться и не будет срабатывать прикрепленная к нему функция, наносящая урон.
И таких функциональных узлов в Blueprint для работы с таймерами достаточно много. С помощью них можно очищать, иначе говоря, удалять таймер, чтобы он более не вызывался, проверять наличие таймера, получать оставшееся время работы, устанавливать его на паузу и прочее.
Blueprint функции для работы с таймером
Установка таймеров

- Set Timer by Event — создает таймер, который вызывает пользовательское событие (делегат). Возвращает Timer Handle для дальнейшего управления (пауза, очистка). Поддерживает зацикливание.
- Set Timer by Function Name — создает таймер, который вызывает функцию по имени. Возвращает Timer Handle для дальнейшего управления (пауза, очистка). Поддерживает зацикливание.
- Set Timer for Next Tick by Event — устанавливает таймер для вызова события на следующем кадре (через делегат).
- Set Timer for Next Tick by Function Name — устанавливает таймер для вызова функции по имени на следующем кадре.
Очистка и инвалидация таймеров

- Clear and Invalidate Timer by Handle — очищает таймер, идентифицированный переданным Timer Handle, то есть останавливает его и инвалидирует сам хэндл, чтобы он больше не был действительным.
- Clear Timer by Function Name — очищает (останавливает) таймер по имени функции. Не инвалидирует Timer Handle, так как работает только с именем.
- Invalidate Timer Handle — устанавливает указанный Timer Handle недействительным, без остановки самого таймера (обычно используется после очистки таймера).
Проверка наличия таймера

- Does Timer Exist by Function Name — возвращает, существует ли таймер, связанный с данной функцией.
- Does Timer Exist by Handle — возвращает, существует ли таймер, связанный с указанным Timer Handle.
Получение времени таймера (прошедшее и оставшееся)

- Get Timer Elapsed Time by Function Name — возвращает, сколько времени прошло с момента запуска таймера, идентифицированного именем функции.
- Get Timer Elapsed Time by Handle — возвращает прошедшее время для таймера по Timer Handle.
- Get Timer Remaining Time by Function Name — возвращает оставшееся время до срабатывания таймера по имени функции.
- Get Timer Remaining Time by Handle — возвращает оставшееся время для таймера по Timer Handle.
Состояние таймера: активность и пауза

- Is Timer Active by Function Name — проверяет, существует ли таймер по имени функции и активен ли он.
- Is Timer Active by Handle — проверяет, существует ли таймер по указанному Timer Handle и активен ли он.
- Is Timer Paused by Function Name — проверяет, существует ли таймер по имени функции и находится ли он в состоянии паузы.
- Is Timer Paused by Handle — проверяет, существует ли таймер по указанному Timer Handle и находится ли он в состоянии паузы.
- Is Valid Timer Handle — проверяет, является ли Timer Handle валидным (действительным) и ссылается ли (ссылался ли ранее) на существующий таймер.
Приостановка и возобновление таймера

- Pause Timer by Function Name — ставит на паузу таймер, определяемый именем функции. Текущие значения времени сохраняются.
- Pause Timer by Handle — ставит на паузу таймер, определяемый по указанному Timer Handle. Текущие значения времени сохраняются.
- Unpause Timer by Function Name — возобновляет ранее поставленный на паузу таймер по имени функции.
- Unpause Timer by Handle — возобновляет ранее поставленный на паузу таймер по указанному Timer Handle.
Timer Manager (менеджер таймеров)
Теперь в упрощённом порядке разберёмся, как же таймеры функционируют внутри самого движка.
Итак, при создании игрового мира в объекте World автоматически создаётся менеджер таймеров — TimerManager, который управляет всеми таймерами в этом мире.
Timer Manager — это система, которая:
- управляет коллекцией активных таймеров;
- отслеживает время каждого таймера и вызывает соответствующие функции или события по истечении заданного интервала;
- позволяет создавать, ставить на паузу, возобновлять и очищать таймеры;
- обеспечивает автоматическую очистку таймеров при уничтожении объектов-владельцев.
При запуске системы в Timer Manager инициализируется внутренний счётчик времени — InternalTime. Этот счётчик увеличивается каждый кадр (с учётом Delta Time) и используется для определения момента срабатывания таймеров.
При создании конкретного таймера в Blueprint система передаёт информацию о нём в Timer Manager, в том числе:
- Timer Handle — уникальный идентификатор таймера в системе;
- объект-владелец (обычно Actor), которому принадлежит таймер;
- ссылка на функцию или событие, которое должно быть вызвано при срабатывании таймера;
- интервал времени, через который таймер должен сработать;
- признак Looping — нужен ли повторный вызов в цикле;
- начальная задержка (Initial Start Delay), если она задана.
Вся эта информация хранится во внутренних структурах движка. В этих структурах также хранится время срабатывания каждого таймера — ExpireTime (или время истечения таймера), которое рассчитывается как сумма текущего InternalTime у менеджера таймеров и заданного интервала времени конкретного таймера.
Далее Timer Manager на каждом тике (Tick) управляет выполнением таймеров. Все таймеры организованы в специальную структуру данных Heap (так называемую «кучу»), в которой они отсортированы по времени срабатывания. В верхней части этой структуры всегда находится таймер с наименьшим ExpireTime (иначе временем истечения), то есть тот таймер, который должен выполниться раньше остальных.
На каждом кадре Timer Manager сравнивает свой текущий InternalTime с ExpireTime таймеров. В рамках одного тика он последовательно обрабатывает все таймеры, у которых ExpireTime меньше или равен текущему значению InternalTime, и вызывает привязанные к ним функции или события.
Таймеры, время истечения которых ещё не наступило, не вызываются. Благодаря этому достигается высокая производительность — система работает только с теми таймерами, которые действительно нужно выполнить в текущем кадре.
После выполнения таймера возможны два варианта:
- если таймер не зациклен (Looping выключен), он удаляется из системы;
- если таймер зациклен, для него пересчитывается новое время выполнения (новый ExpireTime), и он снова помещается в очередь.
Также в обязанности Timer Manager входит управление таймерами через их TimerHandle. Напоминаю, в Blueprint для каждого таймера можно использовать его Handle, чтобы выполнять различные операции — ставить таймер на паузу, возобновлять его или полностью удалять.
При вызове таких узлов в Timer Manager передаётся команда и соответствующий Timer Handle. Менеджер находит нужный таймер и выполняет требуемое действие.
Кроме того, как уже упоминалось, при создании таймера в систему передаётся объект-владелец. Благодаря этому Timer Manager отслеживает, существует ли данный объект в мире. Если объект уничтожается, менеджер автоматически удаляет все таймеры, связанные с ним. Это поведение важно, так как предотвращает попытки вызова функций у уже удалённых объектов и избавляет от потенциальных ошибок и утечек логики.
Почему таймер, а не Event Tick или Delay
В случае, если существует необходимость выполнять какое-то действие циклично с небольшим интервалом между повторами (например, с интервалом в несколько миллисекунд или десятков миллисекунд), и при этом сама логика длится ограниченное время (несколько секунд или минут), то лучше использовать именно таймер с включённым параметром Looping и заданным значением Time, а не событие Event Tick.
Например, это может быть ситуация, когда персонаж заходит в область урона, и пока он находится внутри этой области, ему необходимо периодически наносить урон.
Возникает вопрос: почему именно таймер, если, как мы уже выяснили, все таймеры управляются Timer Manager, который в итоге сравнивает своё текущее время с временем срабатывания таймеров на каждом тике? То есть, по сути, и Event Tick, и таймеры так или иначе зависят от кадров. Это действительно так, но разница заключается в способе обработки логики.
Event Tick вызывается у каждого Актора на каждом кадре (или с заданным интервалом) независимо от того, требуется ли выполнение логики в данный момент или нет. Даже несмотря на то, что Event Tick можно оптимизировать (включать/выключать и уменьшать частоту вызова), он остаётся инструментом для постоянных процессов.
По своему назначению, как мы уже говорили, Event Tick лучше использовать в тех случаях, где логика должна выполняться непрерывно, например, для плавного движения объектов, изменения позиции и поворота, в общем, для любых постоянных процессов, зависящих от каждого кадра.
В кратковременных или периодических задачах Event Tick подходит хуже. В таких ситуациях таймеры оказываются более удобным и эффективным инструментом. Но почему?
- Во-первых, таймеры можно гибко контролировать — их можно ставить на паузу, возобновлять или полностью удалять по Timer Handle.
- Во-вторых, и это ключевой момент, у таймеров более высокая производительность в больших глобальных мирах, потому что Timer Manager не перебирает все таймеры каждый кадр. Вместо этого он использует специальную структуру данных Heap («куча»), в которой таймеры отсортированы по времени срабатывания, и на каждом тике обрабатывает только те таймеры, у которых время уже наступило. Остальные таймеры система не трогает.
Например, если на сцене будет находиться 1000 Акторов с таймерами, то в конкретный момент времени (в конкретный тик) сработает только часть таймеров, остальные даже не будут обрабатываться.
В то время как при использовании Event Tick системе придётся вызывать Tick у всех 1000 Акторов, даже если внутри Tick никакой логики фактически не выполняется. Если же уменьшить частоту Tick, то всё равно все Акторы будут участвовать в обработке, просто часть вызовов будет пропускаться.
Таким образом, при большом количестве объектов таймеры дают более эффективное и масштабируемое решение.
То же самое относится и к простым задержкам, то есть к Delay.
Delay — это узел задержки выполнения кода в Blueprint. Он позволяет отложить выполнение логики на заданное время. Опять же, существует мнение, что Delay — это некое «зло», и его всегда нужно заменять таймерами (без опции Looping). Как и в случае с Event Tick, это не совсем корректный подход.

Delay — это нормальный инструмент, который очень хорошо подходит для целей прототипирования, для быстрых проверок игровой логики или простых последовательностей действий. Например, когда нужно быстро проверить механику и добавить паузу между действиями, Delay — это удобное и простое решение.
Однако при написании финального (Production) кода Delay лучше заменять на таймеры.
- Во-первых, в отличие от Delay, таймерами можно управлять. Как уже говорилось ранее, их можно поставить на паузу, можно отменить или удалить, можно проверить их состояние. Delay же после запуска уже нельзя остановить или изменить.
- Во-вторых, как и в случае с Event Tick, важную роль играет производительность. Каждый Delay в движке рассматривается как отдельный скрытый подпроцесс, который отслеживается системой и проверяется на каждом кадре.
Если, например, в логике 1000 Акторов используют Delay, то системе придётся отслеживать все эти задержки, фактически проверять их состояние на каждом кадре.
Если же ту же задачу реализовать через таймеры, то, как мы знаем, все они управляются централизованно через Timer Manager, где на каждом тике обрабатываются только те таймеры, у которых истекло время. Остальные таймеры не участвуют в вычислениях. Таким образом, Timer Manager работает более эффективно за счёт выборочной обработки таймеров, тогда как Delay создаёт множество независимых ожидающих подпроцессов.
В итоге Event Tick следует использовать для непрерывных, постоянных процессов, которые должны обновляться каждый кадр для создания плавности. Таймеры — для периодических или ограниченных по времени задач. Delay — используется как быстрый инструмент для прототипирования и простых сценариев, в более сложной логике или в итоговом Production коде его лучше заменять таймерами.
Напоминаю про мою бесплатную книгу по Blueprint для Unreal Engine.
Основная цель книги — дать общий, целостный и понятный обзор системы Blueprint. Книга предлагает взгляд с высоты «птичьего полёта» — ясную и чёткую карту игрового мира Unreal Engine, которая поможет увидеть ключевые взаимосвязи и понять, как устроена система визуального скриптинга.
Зарегистрироваться в ЛК и скачать книгу [Blueprints. Взгляд с высоты «птичьего полёта»]










