C++ How I made timers work when game paused

Hello everyone

What are you thoughts about how I made timets work even when game is paused?
Here is the code

UCLASS()
class APausedTimerManagerTicker : public AActor
{
	GENERATED_BODY()
	APausedTimerManagerTicker();
	virtual void Tick(float DeltaSeconds) override;
};

inline APausedTimerManagerTicker::APausedTimerManagerTicker()
{
	PrimaryActorTick.bCanEverTick = true;
	PrimaryActorTick.bTickEvenWhenPaused = true;
}

inline void APausedTimerManagerTicker::Tick(float DeltaSeconds)
{
	Super::Tick(DeltaSeconds);
	if(GetWorld() && GetWorld()->IsPaused())
	{
		GetWorld()->GetTimerManager().Tick(DeltaSeconds);
	}
}

That seems like a clever solution. Does it work?

Yes it does work, but . . .

In my game I have resources like metal, wood, that are being collected every second. And they work using timers, and it’s obvious that they should be paused when game is paused. But when this class is used they collect resources even when game is paused, which is wrong.

Now I am thinking about writing own TimerManager that will allow to mark any single Timer as TickWhenPause = true, so I could controll which timers I want to tick when paused and which ones I dont want to.

Yes I am a newbie in UE4 and maybe there exist more correct solution, but I am not aware of it right now(((

I honestly think you’d be well placed to turn this into a pull request for the engine on github - This seems like a feature that a lot of people would find very useful

Really? I think you overestimating me)

Hi, about writing your own TimerManager that will allow any single Timer works when game pause, do you have any follow-up solution? I would like to know, thanks!

Unless you’re going to override TimerManager and build it o ut to handle that sort of thing, because you need it a lot for some reason, then it’s easiest just to do a Tick in the object that needs it

This is a huge workaround and it could cause a lot of issues. I don’t think a pull request like this will be accepted.

I modified your system by adding a timer call function on the real-time actor itself. By adding a link to it to your subsystem. Now I can run timers through it using real time. Maybe it will help others!

#include "RealTimeActor.h"

#include "Kismet/GameplayStatics.h"
#include "GameSystem.h"

// Sets default values
ARealTimeActor::ARealTimeActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	PrimaryActorTick.bTickEvenWhenPaused = true;
}

// Called when the game starts or when spawned
void ARealTimeActor::BeginPlay()
{
	Super::BeginPlay();
	
	UGameInstance* GameInstance = Cast<UGameInstance>(UGameplayStatics::GetGameInstance(GetWorld()));
	UGameSystem* GameSystem = GameInstance->GetSubsystem<UGameSystem>();
	GameSystem->RealTimeActor = this;
}

// Called every frame
void ARealTimeActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

void ARealTimeActor::StartRealTimer(FTimerHandle TimerHandle, FTimerDelegate TimerDelegate, float time, bool bLoop)
{
	GetWorldTimerManager().SetTimer(TimerHandle, TimerDelegate, time, bLoop);
}