Timer code works fine except for this instance. Unsure of why timeout isnt working

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Zalinho

Im working on a basic timer and have no clue as to why the code is not working. This same code I have used on another scene and works fine yet on the current scene i am trying to program, the timeout never occurs. I made some tester code to figure out why but i still cant see the issue.

var on = true
func _process(delta):
   if on == true:
      $Timer.start()
      if($Timer.time_left) > 0:
		print(str($Timer.time_left))
      else:
		print("OFF")
   else:
      print("TIMER WORKED")

with the timeout code correctly connected

func _on_timer_timeout():
   print("TIMING OUT")
   on = false

I dont know if im being stupid or something but i just cant see whats wrong with the code. The output is stuck on 1 so the time left is always 1 but i don’t see why. Nothing else happens and the timeout never occurs. This same code complicated with more code works in another scene but here it doesn’t which is why im struggling.

the timer process mode is set to idle, autostart off and oneshot off.

:bust_in_silhouette: Reply From: MitchReidNZ

Having this in _process() isn’t the best place.
Every frame (ie, 60 times a second) you are calling $Timer.start()
The first frame that’s fine, it’ll start the timer how you expect.
However, check out the documentation for Start - Timer — Godot Engine (stable) documentation in English
Calling it on a running timer will reset the wait_time back to it’s starting point.

So, every frame you’re starting the timer again from scratch.

Easy fix is to change your if statement from:

if on == true:

to

if on == true and $Timer.is_stopped():

Which can be simplified to:

if on and $Timer.is_stopped():

By doing this you first check whether the timer is already running, so you’ll only start the timer if it’s not already running.

This means on the first frame you’ll start the timer, then on every subsequent frame you’ll print out “TIMER WORKED”

Edit: Fixing random italics