0 votes

I have a command in physics process that checks how many enemies in a group there are, and if the number is equal to 0, it should start a timer. The issue is, since it's in delta, it starts the timer every frame. I need a way to check every frame how many enemies are left, but then start a timer once it reaches 0. I've tried setting a bool to true instead, but I don't really have a place to start the timer. I can't just call a separate function with the start command in it, because it would still be called every frame. I'd appreciate some help with this :(

in Engine by (103 points)

2 Answers

0 votes

You do as you thought - you set a bool to see if the timer was already called.

Something like, to keep it simple:

var timer_already_called := false

func _process(delta: float) -> void:
    if (not timer_already_called 
    and check_number_of_enemies_in_group() == 0):
        start_timer()
        timer_already_called = true

If you're worried that running a code like that every frame would hinder performance due to the counting of objects in a group even after you don't need it anymore, don't be: just order the conditions in the IF statement to check the variable first and count the group after.

(Since the IF is an AND statement, as soon as any condition returns false it doesn't need to keep evaluating the rest of the conditions - the end result is already false, so it won't cause any performance issue.)

by (19 points)
edited by
0 votes

I think your idea with a boolean works just fine. The following example script is with a minimal scene containing a Node as the root with a child Timer Node called Timer. Timer Node also has the signal timeout() connected to _on_Timer_timeout() in NodeĀ“s script. enemies_left() serves as a placeholder for your mentioned function.

extends Node

var timer_inactive = true

func _ready():
    $Timer.one_shot = true

func _physics_process(_delta):
    if timer_inactive and enemies_left() == 0:
        timer_inactive = !timer_inactive
        $Timer.start()

func enemies_left():
    return 0

func _on_Timer_timeout():
    #do stuff
    timer_inactive = true

Make sure oneshot is enabled in your Timer Node. By evaluating timer_inactive before enemies_left(), enemies_left() is only called when timer_inactive is true

by (22 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.