Attack cooldown

Godot Version

4.0

Question

So i am currently working on a game and i need to add a attack cooldown. I use signaling and components and i cant figure how to make it so it repeats its attack after the timeout.
this is the hitbox component code
extends Area2D

signal Hit(Damage,area)

@onready var HealthComponent: Node2D = $“…/HealthComponent”

func OnHit(Damage: Variant) → void:
HealthComponent.damage(Damage)
print(“OnHit”)

and this is the atack component code

extends Area2D
signal Attack()
signal Hit(Damage)
@export var Damage: int
var time = true
var enemy_in_range = false

func OnAttack(area, Enemys):

if Enemys.count(area) != 0:
	for i in range(Enemys.count(area)):
		Enemys[i].emit_signal("Hit", Damage)
		print("2")

func _on_area_entered(area):

Signal from the same node, i.e. from AttackComponent (it is an Area2D node).

	var Enemys = self.get_overlapping_areas()
	enemy_in_range = true
	self.emit_signal("Attack",area, Enemys)

func _on_area_exited(area):
enemy_in_range = false

func _on_timer_timeout(area):
return
ill reply with pictures to show signals and other stuff. but basically ive already implemented a attack cooldown into a game before but this doesnt work because when i try to call the attack function on the timer timeout or make it so when the timer is timed out attack cooldown = true and then if attack cooldown = true then do the stuff then it it will attack once on the conditions but i cant figure out how to make it repeat attacks


Hit box

atttack
and then health which isnt neccesary to post?

these are components of the characters and are saved as scenes. It is ai combat so no player

Couldn’t you just add a var like ‘can_shoot’ that needs to be true in order to shoot?
This would make the timer issue a lot easier since you could just set the var on false after shooting and set it back on true after your cooldown.
That way, you can shoot once, and after the cooldown you can shoot again.
In short form:

  1. Add a var( bool)
  2. Set ut to true
  3. Make it so that the function only works with that var being true
  4. Set the var to false after shooting
  5. Set it back to true in the timer function

Hope this helps

Try something like this:

var fire_cadence = 0.2
var fire_cooldown = 0.0

func _process(delta):
	if fire_cooldown <= 0:
		fire()
	fire_cooldown -= delta

func fire():
	fire_cooldown = fire_cadence
	# do the attack

If 200 ms is too fast, increase fire_cadence.

2 Likes

I think I tried this and will try again, but I think that the problem with this is that the attack is emitted through a sigal. Upon entering the area, a signal is given to the attack function, which gets the overlaping areas, so it will get the areas and then send the signal once and cause an attack once. If i try to make it true, then attack() or something else, then it wont work because it lacks the area signal and it wont attack anything, or it will still just attack once, but only if the cooldown is true

Hm, then I’m sorry to say that I have no other idea on how to fix it, the timer was my only guess…hope you can solve it tho

So, one option would be to put an area2d on the enemy you want shooting, and one representing hitbox.

Set a signal area_shape_entered on shooter, connected to func in shooters code. You can use it to confirm area target. Attatch argument bool as true. Use that to set var can_shoot = area_entered_bool

Set signal area_shape_exited connected to same func, pass argument bool false, and set var can_shoot = area_entered_bool.

Somewhere else in shooter code set up timer func.

In physics_process you can now have an if statement.
If can_shoot and timer_done:
Shoot()