timer wont stop(resolved)

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

i dont know whats happening in my code but my timer starts and dont end here my code

    extends Area3D

var counter = 0
var time_sec=5

func _ready():
	pass 

func _process(delta):
	if counter <= 0:
		$Control/Label.text = str("KILLED ALL")
		$Timer.start(time_sec)
	if $Timer.is_stopped():
		print("TIMER STOPPED")
	else:
		print("TIMER GOING")


func _on_area_entered(area):
	if area.is_in_group("enemy"):
		counter += 1


func _on_area_exited(area):
	if area.is_in_group("enemy"):
		counter -= 1
	$Control/Label.text = str("enemies left: ", counter)
	print(counter)


func _on_body_entered(body):
	if body.is_in_group("enemy"):
		counter += 1
	$Control/Label.text = str("enemies left: ", counter)


func _on_body_exited(body):
	if body.is_in_group("enemy"):
		counter -= 1
	$Control/Label.text = str("enemies left: ", counter)
	print(counter)


func _on_timer_timeout():
	print("TIMER END")
	Global.goto_scene("res://scenes/fase01.tscn")
   

on this code the timer starts but neve end it says timer going and wont stop idk why this
obs: if i put timer.start in ready it go normal and stops for some reason

Are you sure the timer is being started? If so, what happens if you print its time_left property in your _process() function? Does it appear to be counting down as expected?

jgodfrey | 2023-05-25 20:34

isn’t saying nothin in output

aikame | 2023-05-25 23:35

Errrr… That doesn’t make any sense I don’t think. Are you sure the print code is executing? Where did you add it and (specifically) what does it look like?

jgodfrey | 2023-05-25 23:47

i fix it but its saying zero and when starts says 5 and dont goes down

aikame | 2023-05-25 23:50

This should be pretty simple to fix, but diagnosing it in a forum post is difficult - especially since we can’t see what changes you’ve actually made based on the input already provided. I’d be happy to look at the project if it’s available online somewhere. Otherwise, I’m not sure what else to offer…

jgodfrey | 2023-05-26 00:01

i dont have an example rignt now but heres the entire project almost 300mb
the script is the “enemiesC” and the scene is “fase_1” in the “area3D2” has the timer its a mess and the projec is half portuquese

aikame | 2023-05-26 00:35

Hmmm… Attempting to load that project into Godot 4.0.2 just segfaults here ATM…

What’s the wait_time set for on your timer? What happens if you assign a wait_time value in _ready()?

jgodfrey | 2023-05-26 01:02

the wait time is 5 seconds and when i put this in ready change nothing

aikame | 2023-05-26 01:31

Ah, I guess I misread your earlier comment when I asked you to print start_time. I thought you said it was printing 0, but now I see it was printing 5 as expected.

So, next thought…

Are you sure your $Timer.start() is getting called from _process()? What happens if you print something from just above that start() call? Do you see it get printed?

jgodfrey | 2023-05-26 01:39

i didnt understand but i coded thath if theres no enemies it starts

aikame | 2023-05-26 01:44

I meant something like this…

  if counter <= 0:
        $Control/Label.text = str("KILLED ALL")
        print("Starting Timer") # <---- Add something like this
        $Timer.start(time_sec)

Do you see that get printed? If so, how many times?

jgodfrey | 2023-05-26 01:51

infinite times

aikame | 2023-05-26 01:55

Ah, wait…

Why are you passing time_sec into that start() call? That’ll reset the wait_time() each time that code executes. And, I bet it’s executing over and over again when counter <=0 - since it’s in process().

Change that to just:

$Timer.start()

… and see how it works.

jgodfrey | 2023-05-26 01:56

its hapening the same thing the timer dont go down

aikame | 2023-05-26 02:01

And, maybe better yet, something like:

if $Timer.is_stopped():
    $Timer.start()

That’ll prevent you from calling start() when the timer is already running…

jgodfrey | 2023-05-26 02:02

it workeed thanks so much

aikame | 2023-05-26 02:11

:bust_in_silhouette: Reply From: Tom Mertz

You might need to set your timer’sone_shot to true in the inspector (or through code). By default, this is false and timer’s will repeat indefinitely unless you stop them. The timeout signal is called when the timer reaches 0, not when it is stopped.

So, try to either set your timer’s one_shot to true, or call $Timer.stop() in your timeout.

isn’t working either

aikame | 2023-05-25 23:46

:bust_in_silhouette: Reply From: jgodfrey

Based on the lengthy discussion above, the ultimate answer here was to change this code:

func _process(delta):
    if counter <= 0:
        $Control/Label.text = str("KILLED ALL")
        $Timer.start(time_sec)

to this…

func _process(delta):
    if counter <= 0:
        $Control/Label.text = str("KILLED ALL")
        if $Timer.is_stopped:
            $Timer.start(time_sec)

Which will only start the timer if it’s not currently running. Without that guard, the $Timer.start() was being called in each frame (when the counter condition was met). And, since each call to start() resets the timer’s remaining time to the initial wait_time value, the timer could never count down.

Pretty obvious in hindsight… :frowning: