0 votes

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()
in Engine by (66 points)

2 Answers

+1 vote

You can use signal from Area2D node. If you are new to signals, check this tutorial: http://kidscancode.org/blog/2017/02/godot_101_06/

Then you can adapt to your code.

by (191 points)

Thanks for your advice. I was using a signal first (bodyenter) 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.

+1 vote

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.

by (840 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.