Can you make Area2D object disappear in one frame?

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

Hi. I have a little experimental project where I test some functionalities. I have worked out everything I have needed so far apart from a flying bullet which is represented by Area2D node.
The problem I’m trying to solve is that when the bullet hits a PhysicalBody and when hide() is called I can see the bullet several frames after the hit (so it travels behind the border of the object’s collision shape). Is there a way to hide the bullet right at the moment when body entered it with just Area2D?
Please excuse the code as it’s a little messy (it’s experimental as I wrote before). Thank you.

extends Area2D

var bullet_direction
var shape_owners = []
var overlapping_bodies = []

const BULLET_SPEED = 400

func init(direction):

	bullet_direction = direction

func _ready():

	shape_owners = get_shape_owners()
	overlapping_bodies = get_overlapping_bodies()
	if overlapping_bodies.size() > 0:
		hide()

func _process(delta):

	if detect_overlap_world():
		hide()
		for x in shape_owners:
			shape_owner_clear_shapes(shape_owners[x])
			queue_free()

	translate(bullet_direction * BULLET_SPEED * delta)

	overlapping_bodies = get_overlapping_bodies()
	var enemyBody = get_overlap_enemy()
	if enemyBody:
		hit_enemy(enemyBody)

func detect_overlap_world():

	if overlapping_bodies.size() > 0:
		for x in overlapping_bodies.size():
			if !overlapping_bodies[x].is_in_group("Enemy"):
				return true
	return false

func get_overlap_enemy():
	var overlapping_bodies = get_overlapping_bodies()
	if overlapping_bodies.size() == 1:
		if overlapping_bodies[0].is_in_group("Enemy"):
			return overlapping_bodies[0]
	return

func hit_enemy(body):

	body.get_hit()
	queue_free()
:bust_in_silhouette: Reply From: gtkampos

You can use signal from Area2D node. If you are new to signals, check this tutorial: Godot 101 - Part 6: Area-based Collisions · KCC Blog

Then you can adapt to your code.

Thanks for your advice. I was using a signal first (body_enter) and the result was the same. I have working solution now when I use KinematicBody2D for world collision of the bullet and Area2D trigger for collision with an enemy so that’s good.
Still I would like to know if it is possible that Area2D is being hidden some frames deay after it was told to be hidden with the hide() function in a body_enter() signal.

Paar | 2018-02-08 21:12

:bust_in_silhouette: Reply From: Footurist

Don’t get stuck with bad ideas.

Why not calling bullet.queue_free() right after the collision was detected? Use call_deferred(string method_name) if it’s still in collision or use a Timer with a very small delay like 0.025 or something.

If you still want the delay units in frames, then count frames in func _process(delta) with a variable and set a boolean to true after some frames, which will trigger hide(). I recommend avoiding this overcomplication.