Hi all

I have a character shooting projectiles which is rate-limited. When these projectiles enter a 2D Body, it should decrease the health of the enemy until it dies. Problem is that not all projectiles are detected, only every third projectile is detected, like the below.

1 (detected) --> 2 (not detected) --> 3 (not detected) --> 4 (detected) --> etc....

Here is the code on the enemy's 2D body:

func _on_area_2d_body_entered(body):
	if body.name == "Character":
		body.taking_damage()
		Game.lose_life()
	elif body.name == "Projectile":
		if health > 0:
			health -= 1
			body.queue_free()
		else:
			body.queue_free()
			queue_free()

Any help appreciated.

Hey fnanfne! Gonna need a bit more information to assist. Is the script attached to the character or the projectile? What does is the initial value of health?

    retroshark

    Hey retroshark

    The script above is on the enemy. I put the health at 20 and was printing whenever a projectile passes the 2d_body. I can see the health decrement by one, but only every third or so projectile registers. So out of every 10 projectiles that hit the 2d_body, only 3 health points are lost.

    retroshark

    In bed and of course can’t stop thinking about this problem. I was thinking about the behaviour and wondering if the projectile cannot “register” itself multiple times. So when there are two/thee/more projectiles inside an enemy’s 2d_body, only one of them signals.

    Not sure but I could try to “delete” the projectile’s 2d_body as soon as it enters the enemy’s 2d_body?

    4am…I try slep now

    afaik each projectile should be an unique entity if you create them with scene instancing.
    The duplicated name string of body entity should not interfere with collision detection callbacks, on body entered is registered for every projectile upon creation.

    Oof, thanks for that info, I'm at a new loss then. Here is a video of the issue, if anyone has some insight to share please.

    In the video you can see and hear projectiles hitting and missing. I increased the firing rate for clarity.

    Most interesting, when the enemy is nearest, more projectiles are "registered", and this rate goes down the further the enemy is.

    [Video removed]

    UPDATE:

    I have now fixed this annoying issue by using Groups instead of the Name. I created a new group calle dProjectiles and added a new test projectile in this group. So, instead of using body.name == "Plasmaball", I used body.is_in_group("Projectiles"). This should do the same thing really, so I'm not sure what the logic is here, but I'm so glad I got it working.

    Plasmaball is the old projectile with the same name.

    func _on_area_2d_body_entered(body):
    if body.name == "Plasmaball":
    $ProjectileHit.play()
    body.queue_free()
    elif body.is_in_group("Projectiles"):
    $ProjectileHit.play()
    body.queue_free()

      Ayeee glad to hear that you had success in finding a solution! My suggestions, for future reference of course, would be having this execute in the projectile's script.

      It is significantly easier to reference the body that it is colliding with and decrement health like this body.health -= 1 directly in the function attached to the signal.

      fnanfne hmmm that's weird, maybe you should post an issue if your problem is 100% reproducible.