Как то можно сделать чтобы таймеры работали когда игра на паузе?
Ах, таймеры и пауза — пара, которая часто не ладит. Ставишь игру на паузу, а таймеры такие:
"Ну ладно, отдохнём...". Но иногда тебе нужно, чтобы они не халтурили, а продолжали тикать даже во время паузы. Давайте разберёмся, как это сделать.
1. Таймер через SetTimer с параметром bTimerExecutesInPause
Самый простой способ: при вызове
SetTimer указываем параметр
bTimerExecutesInPause равным true. Вот пример на C++:
FTimerHandle TimerHandle;
GetWorld()->GetTimerManager().SetTimer(
TimerHandle,
this,
&AMyActor::MyTimerFunction,
1.0f, // Интервал
true, // Повторяющийся
0.0f, // Первая задержка
true // bTimerExecutesInPause
);
Что происходит:
- bTimerExecutesInPause заставляет таймер продолжать работать, даже когда игра на паузе.
- Быстро и удобно, если нужно включить такое поведение для конкретного таймера.
2. Использование FTSTicker вместо стандартного таймера
Если тебе нужен
альтернативный способ без использования стандартного таймера, используй
FTSTicker. Он всегда работает, независимо от паузы.
FTSTicker::GetCoreTicker().AddTicker(
FTickerDelegate::CreateLambda([this](float DeltaTime)
{
// Ваш код здесь
return true; // Возвращаем true чтобы продолжать тикать
})
);
Плюсы:
- Работает на движковом уровне, не завися от игрового времени.
- Полностью игнорирует паузу.
Минусы:
- Нужно вручную управлять логикой, если требуется повторение.
3. Переопределение IsPauseable для объектов
Если нужно, чтобы все таймеры в конкретном объекте работали во время паузы, можно переопределить метод
IsPauseable в классе вашего объекта:
virtual bool IsPauseable() const override
{
return false; // Объект не будет паузиться
}
Что это делает:
- Указывает движку, что данный объект не паузается.
- Все таймеры и события этого объекта будут работать во время паузы.
4. Таймеры в Blueprint: опция "Execute when Paused"
Для тех, кто работает с
Blueprint, всё ещё проще:
- Используйте ноду Set Timer by Event или Set Timer by Function Name.
- В настройках ноды включите опцию "Execute when Paused".
-
UFUNCTION(BlueprintCallable, Category = "Timer")
void StartPauseResistantTimer()
{
FTimerDelegate TimerDelegate;
TimerDelegate.BindUFunction(this, FName("MyTimerFunction"));
GetWorld()->GetTimerManager().SetTimer(
TimerHandle,
TimerDelegate,
1.0f, // Интервал
true, // Повторяющийся
0.0f, // Первая задержка
true // bTimerExecutesInPause
);
}
Теперь этот таймер будет тикать даже в состоянии паузы. Меньше строк кода, больше магии.
5. Динамическое управление паузой через SetTimerPaused
Если нужно включать или выключать паузу у таймеров
во время выполнения, используйте метод
SetTimerPaused:
// Сделать таймер независимым от паузы
GetWorld()->GetTimerManager().SetTimerPaused(TimerHandle, false);
- false — таймер продолжает работать даже в паузе.
- true — таймер будет остановлен.
Это удобно, когда вам нужно
переключать таймеры в зависимости от ситуации.
Важно помнить про таймеры во время паузы
- Игра полностью остановлена — таймеры тоже отдыхают:
Если окно игры свёрнуто или движок приостановлен, таймеры не будут тикать.
- Производительность:
Таймеры, которые работают на паузе, продолжают потреблять ресурсы CPU. Если у тебя много таких таймеров — это может негативно сказаться на производительности.
- Физика и анимации:
Если таймеры используются для управления физикой или анимацией, лучше придерживаться стандартного поведения паузы, чтобы не нарушать консистентность геймплея.
Вывод
Как видишь, способов много, и каждый решает конкретную задачу. Если нужно, чтобы пара таймеров шевелилась даже на паузе —
bTimerExecutesInPause или опция "Execute when Paused" в Blueprint подойдут идеально. А если ты
не любишь компромиссы — подключай FTSTicker и заставляй время тикать всегда.
Как говорится,
"Время не ждёт. Даже на паузе".