My area collision dosen't always work

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Shortanel

Hi I’m working at a space shooter and I have a bug.

func _on_Player_area_entered(area):
	if area.is_in_group("Enemies"):
		print("dead!")
		queue_free()

This should destroy the player is it’s collieded with an enemy but the problem is that it dosen’t do that all the time. I have instances when it needs five times to collide with an enemy to die. Any solution?

P.S. I put the print dead for seeing if it ignore the enemies and it do that.sorry for bad english :))

What happens to the enemy when they collide? Is he destroyed as well? If yes, it could happen that one signal is processed faster than the other and the enemy is already destroyed by the time the player checks for collisions.

Thomas Karcher | 2020-11-27 08:59

Yes the enemies gets destroyed.

it could happen that one signal is processed faster than the other and the enemy is already destroyed by the time the player checks for collisions.

Can somehow been slow down?

Shortanel | 2020-11-27 09:08

:bust_in_silhouette: Reply From: Thomas Karcher

As discussed in the comments, the problem is that the enemy is sometimes destroyed before the player even notices the collision.

Two possible solutions:

  1. Just don’t destroy the enemy when it’s hitting the player:
 # in enemy.gd: Don't die when colliding with the player character
 if (body.name != "Player"): queue_free()
  1. Add a wait time in both the enemy and the player script before the queue_free:
# Wait one frame to make sure the collision was detected by all parties
yield(get_tree(), "idle_frame")
queue_free()

Sorry for late answer now I’m free from work. I try both solutions and:

  1. now destroy the player the animation for enemy explosion is on but the enemy dosent die now
  2. I have the same problem as before.
    I’m doing something wrong?

Shortanel | 2020-11-28 21:20

Strange. I’d need to see the code to understand why #2 doesn’t work. Or you could try solution #3: Like #1, but:

In player.gd, before line queue_free():

if area.has_method("die"): area.die()

In enemy.gd:

func die():
    queue_free()

Thomas Karcher | 2020-11-28 22:28