2D collisions continue even after being removed from tree

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

KinematicBody2D continues to collide via GetSlideCollision with entities that have been removed from the tree.

I have a strange problem. I have a 2D game with poolable, colliding KinematicBody2Ds (C#). When a KinematicBody2D dies, it is removed from tree, has its layer/mask set to 0, moved to a random position far away, etc. However, after the player has collided with and killed another body, every second or 2 the engine will think they are still colliding and damage the player.

Here is my collision code in my KinematicBody2D. Somehow it is confused and colliding with things not in the scene tree, not in the same position, and with different collision masks/layers.

public override void _PhysicsProcess(float delta)
{
    base._PhysicsProcess(delta);
    processCollisions();
}
private void processCollisions()
{
    for (int i = 0; i < this.GetSlideCount(); i++)
    {
        KinematicCollision2D collision = this.GetSlideCollision(i);
        Godot.Object other = collision.Collider;
        takeDamageFrom(other);
        Collidable otherCollidable = other as Collidable;
        if (otherCollidable != null) otherCollidable.takeDamageFrom(this);
    }
}

What happens when the life <= 0:


  virtual public void Kill()
  {
    SetPhysicsProcess(false);
    SetProcess(false);

    if (GetParent() != null) //might be called multiple times
    {
        GetParent().RemoveChild(this);
        Globs.Pools.add(ScenePath, this);
        EmitSignal(nameof(died));
    }

    CollisionLayer = 0;
    CollisionMask = 0;


    float r1 = (float) Globs.rand.NextDouble();
    float r2 = (float) Globs.rand.NextDouble();
    this.GlobalPosition = new Vector2(r1, r2) * -1000000 - new Vector2(-100, -100);

    //kill all components
    List<Component> components = getComponents();
    foreach (Component c in components)
    {
        c.OwnerKilled();
    }
}

Edit: I’ve tried debugging when one of these ghost collisions occur. I’ve seen the other Entity is colliding with player, and it’s GetParent() call is not null. I’m not sure why it’s not being removed.

Edit: If I call QueueFree() in Kill(), then it is STILL COLLIDING! but it will have a NullReferenceException when trying to use collision.Collider for things.

Edit: I swear it wasn’t working earlier, but if I just check to make sure the collision is OK now, then it appears to be working (whether pooling or calling QueueFree()).

        bool badCollision = nOther == null || !nOther.IsInsideTree();
        if (!badCollision)
        { Collidable otherCollidable = other as Collidable; ... }

I have a feeling it might stop working so im gonna wait to accept the answer.