Firing Cooldown?

Godot Version

4.3

Question

Hi all,

I have a problem with my game regarding a cool down firing mechanism, it was working, emphasis on was, before doing heaps of testing getting other things working. Why, it stopped can’t imagine. But instead of making me wait before firing I can spam the fire button.

Anyway the idea is this set the can_fire variable to true in the header section:

var can_fire: bool = true;

after fire button has been his pressed set the variable can_fire to false and get timer to start. On timeout set the variable can_fire to true.

#for the 3rd time - Get the right fracking script
func _on_fire_rate_timer_timeout() -> void:
	print("can fire TRUE");
	#for testing can shoot when timer runs down
	can_fire = true;
	#end

Then within the process() function I have this. If the button is pressed can_fire = false start the timer ready to get set to shoot again.

…
	if(Input.is_action_just_pressed("space_bar") && can_fire):
		shoot_bullet();
		##after firing 0.5 second cool down
		can_fire = false;
		##start the cool cown time
		fire_rate_timer.start();
	##set up to use the left click on the mouse as well
	elif (Input.is_action_just_pressed("left_click") && can_fire ):
		shoot_bullet();
		#after firing 0.5 second cool down
		can_fire = false;
		#start the cool cown time
		fire_rate_timer.start();
	#end if
…

So, what am I doing wrong here?

Regards.

Is the signal still connected? Signals can disconnect for various reasons, e.g. if nodes are deleted and readded in the editor.

Check print whenever functions are called.

It looks, based on your in script comment, that your shoot-function introduces a timer of 0.5 seconds and then sets the can_shoot to false. Cant see if that is the case but if so that would probably explain the problem. Set can_shoot to false instantly and after 0.5 secs wait set it to true.

I’m thinking about these lines:

##after firing 0.5 second cool down
can_fire = false;

What you are doing there in the code looks fine. The problem must be elsewhere.

The only thing I can guess is you have another input somewhere that is triggering the firing of the bullet, or is resetting can_fire somewhere else too.

What does it look like with the print(“can fire TRUE”)? When you fire, how long until that appears again? Or can you fire when it is not printed?

I would also put the can_fire = false and start_timer into the shoot bullet routine. So only the bullet routine changes can_fire and calls the timer.

But this code looks fine TBH.

Did what you suggested and the can_fire was constantly printing true, never once turned to false even for a frame. So, I ended up looking the in process function the only place that could possibly turn it to true ALL the time and there was the ofnding code a simple comment out was all it needed :grinning_face_with_smiling_eyes:.

Why I added that code I can’t remember but it is fixed now.

Thanks for your reply it helped me focus in on what the problem might be instead of being flustered because it was working.

Cheers.

2 Likes

Good idea!!!

1 Like

It is always nice to keep functions doing one thing. For instance the input should just be ‘what do I do when this button is pressed’.

	if Input.is_action_just_pressed("fire_weapon"):
		shoot_bullet();

Then in the input_map, just assign space bar and left click and whatever else to the single action called “fire_weapon”. Then in the future when you want ‘F’ to fire instead, you just change the input map. (Or if let your user change the keys for instance).

PS if this is a bit patronising, I apologise in advance. The shoot_bullet function then calls the “can I fire” function, which is where you do the cooldown and can fire logic.

1 Like

No way to know from this code what the wait_time of the timer node is.

Also, I would suggest consolidating your tests there. e.g.:

if (can_fire and (Input.is_action_just_pressed("space_bar") or Input.is_action_just_pressed("left_click"))):
  # ...

since duplicating that code makes it less maintainable. You might accidentally change one but forget to change the other.

I suggest you move the can_fire and timer logic into the shoot_bullet() function.

function shoot_bullet():
if (!can_fire):
return;
# your fire logic
can_fire = false;
fire_rate_timer.start();

1 Like

This is how i implemented a shoting cooldown, hope it helps:

var ArrowCoolDown: float = 0.6
var NextArrow: float = 0.0

if Input.is_action_just_pressed("Shot"):
if Time.get_ticks_msec() < NextArrow:
return
NextArrow = Time.get_ticks_msec() + ArrowCoolDown * 1000
Shoot_Arrow()
1 Like