Can we change the Timer Manager so that it updates all active timers BEFORE RPC’s are executed? I’m building a relatively simple Cooldown system, and the Server checks to see if the client can fire a weapon when they receive an RPC by checking whether it’s still in cooldown or not.
The problem is, the RPC is executed first before the Timer Manager has updated all timers that frame - so it always triggers as false. I have to do some pretty gross workaround to prevent this from happening.
bool UECGame_AbilityBase::IsInCooldown(const float Tolerance /*= 0.f*/) const
{
// Server can't do the 'Cooldown' check normally for remote clients, because it might be running at a different rate to the clients
// Timer manager may not have ticked this frame when we receive the RPC, so we need to add delta from the previous frame.
if (OwningOrb->Role == ROLE_Authority && !OwningOrb->IsLocallyControlled())
{
if (Tolerance < 0.f)
{
return false;
}
else
{
const UWorld* MyWorld = GetWorld();
const float CoolValue = MyWorld->GetTimerManager().GetTimerRemaining(TH_CooldownTimer);
if (CoolValue <= 0.f)
{
return false;
}
else
{
const float WorldDelta = MyWorld->GetDeltaSeconds();
return CoolValue < (WorldDelta + Tolerance) ? false : true;
}
}
}
else
{
return GetWorld()->GetTimerManager().GetTimerRemaining(TH_CooldownTimer) > 0.f;
}
}
Note that if I do this using an old-school style timer (e.g, save off the time to a float and compare it to GetWorld()->GetTimeSeconds()) then it works fine - but of course I lose the ability to call a function when the time expires. I feel like this is a bit of an oversight in the timer system.