Timer never works properly under area2D?

Godot Version

I am using Godot 4

var is_hit_active = false
var count_hit : int = 0

func _on_body_entered(body):
		#target_body = body
		#apply_damage(body)
		
		if count_hit < 5 and not is_hit_active:
			apply_damage(body)
			$five_hit_crescent_refresh_timer.start()
			is_hit_active = true
		elif count_hit >= 5: # if >= 5, reset count_hit back to 0
			count_hit = 0
			$five_hit_crescent_refresh_timer.stop()
			is_hit_active = false
			queue_free()  # Remove the object after 5 hits

func _on_five_hit_crescent_refresh_timer_timeout():
	print("_on_five_hit_crescent_refresh_timer_timeout!!!")
	is_hit_active = false

func apply_damage(body):
	while count_hit < 5:
		body.knockbackDistance = Vector2(2.0, 2.0)
		body.player_detected(five_hit_crescent_damage_from_player)
		count_hit += 1
		print("five_hit_crescent dealing ", count_hit, ": ", five_hit_crescent_damage_from_player, "damage to ",body)

Question

This is actually a skill made of area2d with a child timer.
The apply_damage(body) is the func that deals damage to the slime.
It works fine but the timer was set to one-shot and 0.5 sec.
It does not work to deal damage every 0.5 second as expected.
image

why some body should enter the body first in order to trigger the refresh timer? what kind of game you making?
how do you increase the count_hit?

You can’t have it both ways.

If it’s “one shot” it will fire ONLY once, not every .5 sec.

1 Like

Hi.
The body is used to detect the enemy, so the skill area2d collide with an enemy, it would deal damage to the enemy through a func player_detected in enemy script.

for the count_hit, i incremented it inside func apply_damage(body). The skill is a 5-hit consecutive skill. So, when the player collided with an enemy and activated the skill by a key, a 5-hit damages dealed to the enemy.

Hope, it makes sense.
Help me please to debug this…

You need to be clearer on what you expect (which is not too difficult to guess, but my guess might not be what YOU expect) and what result you are actually getting. That last part, it’s hazy. You have several print() statements in there; what do they output? Or is the print code never called?

A quick skim over the code, you apply_damage before starting the timer and then enter the method. It might be right, or not, depending on what you want.

Also, how do you link the callback to the timer? I don’t see it’s definition.

I might be misreading things.

2 Likes

why used while count_hit<5?
what is five_hit_crescent_damage_from_player function for ?

problem is above lines only called when the body is entered here again, and this block of code doesnt execute per frame. then the second elif will never be triggered

It might work the way you have it set up if you restart the timer until count_hit == 5

func _on_five_hit_crescent_refresh_timer_timeout(body):
     count_hit += 1
     if count_hit >= 5:
        print("_on_five_hit_crescent_refresh_timer_timeout!!!")
        is_hit_active = false
     else: 
        apply_damage(body)
        $five_hit_crescent_refresh_timer.start()

But you would have to bind body to your timeout signal and remove count_hit += 1 from your apply_damage() function.

1 Like

sancho2. I love you, this idea works finely. Just start the timer, and move count += 1 to the timeout of the timer. :heart_eyes: :heart_eyes: :heart_eyes:

Btw, i did experiment tests in a brand new project, so i can see how to implement your idea. Really thanks. My game should have this issue solved. :slight_smile: