public static bool TryRayCast2D(Vector2 global_position, Vector2 direction, out Raycast2DResult result, uint mask = 1, bool body = true, bool area = false, bool debug = false)
    {
        var outcome = space2D.IntersectRay(global_position, global_position + direction, null, mask, body, area);

        result = new Raycast2DResult();
        var hit = outcome.Count > 0;

        if (hit)
        {
            result.normal   = (Vector2)outcome["normal"];
            result.point    = (Vector2)outcome["position"];
            result.collider = (Node)outcome["collider"];
        }
        if (debug)
        {
            if (hit)
            {
                Debug.DrawLine2D(global_position, result.point, Colors.Red);
                Debug.DrawLine2D(result.point, result.point + result.normal, Colors.Cyan);
            }
            else
            {
                Debug.DrawLine2D(global_position, global_position + direction, Colors.Green);
            }
        }
        return(hit);
    }
    public static bool TryCircleCast2D(Vector2 global_position, Vector2 direction, float radius, out Raycast2DResult result, uint mask = 1, bool body = true, bool area = false, bool debug = false)
    {
        result        = new Raycast2DResult();
        circle.Radius = radius;
        shapeParams.CollideWithAreas  = area;
        shapeParams.CollideWithBodies = body;
        shapeParams.CollisionLayer    = (int)mask;
        shapeParams.SetShape(circle);
        shapeParams.Motion    = direction;
        shapeParams.Transform = new Transform2D(0, global_position);

        var cast = space2D.CastMotion(shapeParams);

        if (cast.Count == 0)
        {
            return(false);
        }
        var origin = global_position + (direction * (float)cast[1]);

        shapeParams.Transform = new Transform2D(0, origin);
        shapeParams.Motion    = Vector2.Zero;
        var info = space2D.GetRestInfo(shapeParams);

        var hit = info.Count > 0;

        if (hit)
        {
            result.normal = (Vector2)info["normal"];
            result.point  = (Vector2)info["point"];
            var col = (Godot.Collections.Dictionary)space2D.IntersectShape(shapeParams, 1)[0];
            result.collider = (Node)col["collider"];
        }

        if (debug)
        {
            var color = Colors.Green;
            if (hit)
            {
                color = Colors.Red;
                Debug.DrawLine2D(global_position, global_position + direction, color, 1);
                Debug.DrawCircle2D(origin, radius, color);
                Debug.DrawLine2D(origin, result.point, Colors.Cyan, 1);
            }
            else
            {
                Debug.DrawLine2D(global_position, global_position + direction, color, 1);
                Debug.DrawCircle2D(global_position + direction, radius, color);
            }
        }
        return(hit);
    }