[SOLVED] How to reset timer? Set with same handle doesn't work?

Hello, can’t seem to reset a timer.
Would you please check code below, and tell me if this approach simply won’t work >(
Thank you!

Can I make an FTimerHandle this way?
Supposing the problem isn’t in saving the handle, can I reset timer by handle?


void AChar::Affected (const EState Key) {

  FTimerHandle Timer; // make a handle ?
  // read Stat, Value, Duration etc from table

  // supposing the problem isn't here -----------
  if (Effects.Add(Key, Timer)) { /* apply effect */ }
  // Effects.Add checks do we already have it, by Key
  // if yes, return false and modify InTimer by ref&
  // if no, return true and save InKey and InTimer internally

  // ---------- should this work ? or is my princess in another castle...
  if (Duration > 0.f) {
    auto Call = FTimerDelegate::CreateLambda( /* remove effect */ );
    GetWorldTimerManager().SetTimer(Timer, Call, Duration, false);
    // PROBLEM: doesn't reset the timer, always sets a new one? :(
  }

}

I want to set the timer, save its handle, and if same effect is added, restart the timer by handle.
Instead, I’m getting added only once (so we know that check works), but the effect is removed multiple times.
Aka, each use adds a new timer until effect removal, instead of resetting the old one.

Thanks a bunch!


SOLUTION

SetTimer with the same handle indeed does reset the timer as expected.
The problem was that just by declaring an FTimerHandle Timer; you generate an invalid handle (basically an uint64 0).
The handle is only filled once it was used by SetTimer, therefore you need to save it after the timer was set.



// bad
FTimerHandle Timer;
MyTimers* = Timer;
SetTimer(Timer, ...);

// good
FTimerHandle Timer;
SetTimer(Timer, ...);
MyTimers* = Timer;


Cheers

1 Like

put this in your .h file.



FTimerHandle Timer;

This will clear the timer so you can use it again.


if (GetWorldTimerManager().IsTimerActive(Timer))
GetWorldTimerManager()).ClearTimer(Timer);

When you need to restart it just use your SetTimer line.

1 Like

Gameplay Timers

Thank you for your responses.

@gamepainters ok, I’ma try that. Was thinking no - because ClearTimer has the following to say:

  • Invalidates the timer handle as it should no longer be used.
    and calls
    /** Explicitly clear handle */ void Invalidate() { Handle = 0; }

I’m a try. I guess if it works for you, it’ll work for me.

@STRiFE.x ? that’s a link to the docs, yes. Yes, I’ve read it. Could you be a bit more precise :slight_smile: there’s nothing on there regarding restarting. Maybe I missed it. Could you pls point me?
There’s this bit
“Calling SetTimer with an existing timer handle will clear the timer referenced by that timer handle and replace it with a new one.”
but that’s what I was doing, no?

Cheers

Your


FTimerHandle Timer

is a local variable to your function, each time the function is called it is a completely new variable, not the same as the last time you accessed it. The key point here is to change it to be a class variable as gamepainters pointed. This is not about how the TimerHandle works, this is just how C++ works.

Ok I think I got it. It’s the SetTimer that fills the handle, not just constructing it. (It is constructed with an invalid handle of uint64 0).

@_brunocoimbra thanks for your response. I was saving the handle in a sub-struct by ref (during Effects.Add), but the problem was I was saving it before filling it with SetTimer, therefore always saving an invalid handle.

If the handle is in the .h file, When you clear the timer. You are stopping the timer it self, not destroying the handle. So it is ready for use thru out the file anytime you need it.

The handle will always be ready to be used in that class or classes (depending on how you define it > public: protected: private:). I my self have been setting mine up private: So they are only used in the class i defined the handle in.

I did set one up on public as i needed another class to run the clear timer on it. So i had to use public on it.

Hey man could u explain me abit more about the Handle Functionalities because i rly dont get it.
Im able to setup a simple timer that works fine for a single execusion when im setting up the Timerhandle in the cpp File. I tried to setup the Handle now in the Headerfile but when im doin this my Timer dont work anymore… I tried it now by referencing my Timer in the cpp File but still the same :man_shrugging:

Im pretty lost now and dont know what is wrong now ^^

cpp file:

.h file:

I rly hope u can help me ^^

Sure here is way to use the handle. You defined it right in the .h file, that is exactly how they should be.

Just for clarification in .h file set vars like so.

UPROPERTY()
bool bIsTrue;

UPROPERTY()
FTimerHandle TimerHandle_DoWhatEver;

To use them in your cpp file, use it like this. Always check the timer that it is not running or it is false before you set it, so you do not get a double timer.

bIsTrue = false;

 if (!GetWorldTimerManager().IsTimerActive(TimerHandle_DoWhatEver))
 {
	GetWorldTimerManager().SetTimer(TimerHandle_DoWhatEver, this, &AYourClass::SomeFunction, 1.0f, true);
 }

Example: How to use it as a timer check to pause code until a certain condition is true.
You can use this as a pause timer also. Such as, set a timer to true to go to another function. in the other function, the 1st check will be a bool that returns if its false and when it gets set to true it lets you thru the next function and clears the timer.

Example

void AYourClass::SomeFunction()
{
     //get set to true somewhere else in your code to let you thru and clear the timer.
     if(!bIsTrue)
    {
       return;
    }

    //CHECK IS TIMER RUNNING, IF SO CLEAR IT.
    if ( GetWorldTimerManager().IsTimerActive(TimerHandle_DoWhatEver))
    {
    GetWorldTimerManager().ClearTimer(TimerHandle_DoWhatEver);
    }
   // Continue on with your code
}

One other thing to mention is, if you set your timer to false it will fire when the timer float has run out.
You do not need to clear a false timer as they are set false once they are fired off. You can just reuse it and i wil work fine but true timer you must clear them or you will get to many running and cause a major problem.

Hope this helps.

Just one correction if you call SetTimer on a timer that is already running, the function will replace the current time as stated here. The timer will essentially be reset.

1 Like

If you provide a time of less or equal 0 to the timer, it will clear the timer also.

You didn’t clarify this: One other thing to mention is, if you set your timer to false it will fire when the timer float has run out.
You do not need to clear a false timer as they are set false once they are fired off. You can just reuse it and i wil work fine but true timer you must clear them or you will get to many running and cause a major problem.

What is a true timer and a false timer?

I assume you are referring to the timer looping. Clarification is important.

You also do not need to check if the timer is active to call ClearTimer. It is redundant.

last part of the line you set it to true or false, that is what i am calling the true, false. A true will fire every second or whatever the float is, Timer will keep firing until it is cleared or as stated above when it is recalled it will reset it and start it over.

A false will fire only when the float timer runs out and it will clear it self and can be reused instantly.

Just go get into all the timer code like Kaidoom15 did and read all the comments on the timer stuff, best way to learn it, as they wrote it. There is alot of timer stuff that we have not even came close to covering. Pausing timers, checking how much time left on the timer. Just go find that stuff and set read for a bit. You will find all the timer info you are needing.

I am fully aware of timers, i have been using Unreal for 5+ years, and i program in unreal for work. I was just pointing out you called it a True timer or False timer, which makes no sense. And will just confuse people.

Whatever, set them how you like. Hey while you are at it go open up the .sav file with notepad tell me what it says.