126 lines
4.3 KiB
C#
126 lines
4.3 KiB
C#
namespace GodotHelpers.Raycasts;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using Godot;
|
|
using Godot.Collections;
|
|
using SJK.Functional;
|
|
|
|
/// <summary>
|
|
/// Extensions for <see cref="PhysicsDirectSpaceState3D"/>.
|
|
/// Allows for an static way of casting an godot Raycast3D.
|
|
/// </summary>
|
|
public static class RaycastExtensions
|
|
{
|
|
// --- 3D ---
|
|
|
|
public static RaycastResult3D? RaycastEx(this PhysicsDirectSpaceState3D space, Vector3 from, Vector3 to, uint collisionMask = uint.MaxValue, Rid[]? exclude = null, bool hitFromInside = false)
|
|
{
|
|
var query = new PhysicsRayQueryParameters3D
|
|
{
|
|
From = from,
|
|
To = to,
|
|
CollisionMask = collisionMask,
|
|
HitFromInside = hitFromInside,
|
|
};
|
|
if (exclude != null)
|
|
query.Exclude = new Array<Rid>(exclude);
|
|
|
|
var result = space.IntersectRay(query);
|
|
if (result.Count == 0)
|
|
return null;
|
|
|
|
return new RaycastResult3D(
|
|
Collider: result["collider"].AsGodotObject(),
|
|
ColliderId: result["collider_id"].AsInt32(),
|
|
Rid: (Rid)result["rid"],
|
|
Shape: result["shape"].AsInt32(),
|
|
Position: result["position"].AsVector3(),
|
|
Normal: result["normal"].AsVector3()
|
|
);
|
|
}
|
|
|
|
public static bool RaycastHitEx(this PhysicsDirectSpaceState3D space, Vector3 from, Vector3 to, [NotNullWhen(true)] out RaycastResult3D hit, uint collisionMask = uint.MaxValue, Rid[]? exclude = null, bool hitFromInside = false)
|
|
{
|
|
hit = space.RaycastEx(from, to, collisionMask, exclude, hitFromInside)!;
|
|
return hit is not null;
|
|
}
|
|
|
|
// --- 2D ---
|
|
|
|
/// <summary>
|
|
/// Extensions for <see cref="PhysicsDirectSpaceState2D"/>.
|
|
/// Allows for an static way of casting an godot Raycast3D.
|
|
/// </summary>
|
|
public static RaycastResult2D? RaycastEx(this PhysicsDirectSpaceState2D space, Vector2 from, Vector2 to, uint collisionMask = uint.MaxValue, Rid[]? exclude = null, bool hitFromInside = false)
|
|
{
|
|
var query = new PhysicsRayQueryParameters2D
|
|
{
|
|
From = from,
|
|
To = to,
|
|
CollisionMask = collisionMask,
|
|
HitFromInside = hitFromInside,
|
|
};
|
|
if (exclude != null)
|
|
query.Exclude = new Array<Rid>(exclude);
|
|
|
|
var result = space.IntersectRay(query);
|
|
if (result.Count == 0)
|
|
return null;
|
|
|
|
return new RaycastResult2D(
|
|
Collider: result["collider"].AsGodotObject(),
|
|
ColliderId: result["collider_id"].AsInt32(),
|
|
Rid: (Rid)result["rid"],
|
|
Shape: result["shape"].AsInt32(),
|
|
Position: result["position"].AsVector2(),
|
|
Normal: result["normal"].AsVector2()
|
|
);
|
|
}
|
|
public static IOption<RaycastResult2D> RaycastOptionEx(this PhysicsDirectSpaceState2D space, Vector2 from, Vector2 to, uint collisionMask = uint.MaxValue, Rid[]? exclude = null, bool hitFromInside = false)
|
|
=> RaycastEx(space, from, to, collisionMask, exclude, hitFromInside).ToOption();
|
|
|
|
|
|
public static bool RaycastHitEx(this PhysicsDirectSpaceState2D space, Vector2 from, Vector2 to, out RaycastResult2D hit, uint collisionMask = uint.MaxValue, Rid[]? exclude = null, bool hitFromInside = false)
|
|
{
|
|
hit = space.RaycastEx(from, to, collisionMask, exclude, hitFromInside)!;
|
|
return hit is not null;
|
|
}
|
|
// 3D Shape Cast
|
|
public static List<CollisionResultBase> IntersectShapeEx(this PhysicsDirectSpaceState3D space, PhysicsShapeQueryParameters3D query, int maxResults = 32)
|
|
{
|
|
var results = space.IntersectShape(query, maxResults);
|
|
var list = new List<CollisionResultBase>(results.Count);
|
|
|
|
foreach (var dict in results)
|
|
{
|
|
list.Add(new CollisionResultBase(
|
|
Collider: dict["collider"].AsGodotObject(),
|
|
ColliderId: dict["collider_id"].AsInt32(),
|
|
Rid: (Rid)dict["rid"],
|
|
Shape: dict["shape"].AsInt32()
|
|
));
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
// 2D Shape Cast
|
|
public static List<CollisionResultBase> IntersectShapeEx(this PhysicsDirectSpaceState2D space, PhysicsShapeQueryParameters2D query, int maxResults = 32)
|
|
{
|
|
var results = space.IntersectShape(query, maxResults);
|
|
var list = new List<CollisionResultBase>(results.Count);
|
|
|
|
foreach (var dict in results)
|
|
{
|
|
list.Add(new CollisionResultBase(
|
|
Collider: dict["collider"].AsGodotObject(),
|
|
ColliderId: dict["collider_id"].AsInt32(),
|
|
Rid: (Rid)dict["rid"],
|
|
Shape: dict["shape"].AsInt32()
|
|
));
|
|
}
|
|
|
|
return list;
|
|
}
|
|
}
|