Get overlapping bodies on create, then remove instance at the end of the frame with C#

Godot Version

4.2.1 MONO version (Using C#)

Question

I’ll do my best to explain what my problem and question is. I’m using Godot 4.2.1 with C#, creating a 2D platformer game. I’m working on the combat system, and I’d like to achieve the following behaviour:

-“Hurtbox” instance is spawned when the player punches, this inherits Area2D
-Hurtbox instance checks for collisions as soon as it is spawned, and if it collides with a body that inherits my CharacterEntity class, call it’s “Hurt” function
-Hurtbox removes itself at the end of the current frame after checking for collisions.

I have successfully spawned the hurtbox, I have it’s collision masks set up correctly, but I’m not entirely sure how to get the behaviour I want. If I call GetOverlappingBodies in the _Ready function, it always returns an empty array. If I call it in PhysicsProcess and remove the instance at the end of said physics process, it also returns an empty array. If I keep calling GetOverlappingBodies in PhysicsProcess, it does eventually start returning the correct bodies, but I obviously have no way of knowing how “long” I need to stay in Physics process for this to happen. Hooking up the BodyEntered event works, but then I once again have no way of knowing when I should remove the instance, as I have no way of knowing when the current frame “ends” while still being able to get the instances that collided with the hurtbox.

My question is, what’s the correct way to spawn an Area2D, on that same frame check which bodies it’s overlapping with, then remove it right after?

I think correct way will be use ShapeCast2D. I tried before use Area2D but get some issues.

My player Script

    private ShapeCast2D swordShapeCast2D;


    public override void _Ready()
    {
        swordShapeCast2D = GetNode<ShapeCast2D>("ShapeCast2D");
    }

IDamageable is my interface :slight_smile:

    public void Atack()
    {
        for (int i = 0; i < swordShapeCast2D.GetCollisionCount(); i++)
        {
            if (swordShapeCast2D.GetCollider(i) is IDamageable<float> damageable)
            {
                damageable.Damage(SwordDamage);
            }
        }
1 Like

This worked, I ended up changing my approach a bit, and just include the ShapeCast2D inside my player scene. Thank you very much!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.