Shape2D
Shared 2D collision geometry, direct queries and contact pairs.
Shape2D is the base geometry resource. Construct a concrete circle, rectangle, capsule or polygon. The resource is not a body and does not add itself to the physics world. For a normal collider, assign it to Shape on CollisionShape2D, which must be a direct child Entity of the required CollisionObject2D.
Direct Collide methods use the two supplied resources. They neither find objects in EntityTree nor apply body layers/masks or physics response. Each shape has its own local-to-common-space transform. With world transforms, contact points are world-space already; do not apply GlobalTransform to them again.
Choose a method:
- Collide: only an overlap answer at two supplied positions.
- CollideAndGetContacts: points on both surfaces without motion.
- CollideWithMotion and CollideWithMotionAndGetContacts: displacement queries, subject to the limitations below.
The contact array contains pairs [A0,B0,A1,B1,…]: a point on the first shape followed by one on the second. It is not an array of normals or a Collider list. The current implementation allows 16 pairs, or 32 Vector2 values. This complete executed example unpacks pairs and uses separately owned circle resources:
using System;
using Reckfell;
public static class ShapeContacts2D
{
// Both transforms map local shape coordinates into the same query space.
public static (Vector2 A, Vector2 B)[] Query(
Shape2D a, Transform2D transformA, Shape2D b, Transform2D transformB)
{
ArgumentNullException.ThrowIfNull(a);
ArgumentNullException.ThrowIfNull(b);
Vector2[] raw = a.CollideAndGetContacts(transformA, b, transformB);
var pairs = new (Vector2 A, Vector2 B)[raw.Length / 2];
for (int i = 0; i < pairs.Length; i++)
pairs[i] = (raw[2 * i], raw[2 * i + 1]);
return pairs;
}
public static (Vector2 A, Vector2 B)[] Example()
{
using var a = new CircleShape2D { Radius = 10 };
using var b = new CircleShape2D { Radius = 10 };
return Query(a, new Transform2D(0, new Vector2(100, 50)),
b, new Transform2D(0, new Vector2(115, 50)));
}
}In Example, radius-10 circles are placed at (100,50) and (115,50). The check returned one pair: A=(110,50), B=(105,50). Separating the shapes returns an empty array. GetRect() remains local: a query moves neither the resource nor an Entity.
Important motion limitation: for ordinary convex shapes, the SAT path compares swept regions rather than computing exact impact time on two synchronized trajectories. WorldBoundaryShape2D and SeparationRayShape2D use separate algorithms; do not generalize the SAT description to every shape type. In the check, radius-2 circles started at (100,50) and (120,50), both received displacement (30,0), and CollideWithMotion returned true. Their distance during such joint movement stays 20: true here does not prove a real impact. Do not treat the result as impact time, a safe movement fraction or a substitute for physics-body movement. Motion means displacement, not velocity; delta is not multiplied automatically.
Normally leave CustomSolverBias at 0 to use the space bias. Its setter does not emit Changed. Draw appends commands to an existing CanvasItem; it creates no collider. The resource owns its shape RID: do not free it separately through PhysicsServer2D. A shared resource remains shared by all users.
Static and swept overlaps, contact-pair order and coordinates, the exact example, bias and local bounds were checked in the installed Windows runtime. Draw was checked only for headless command submission. The 16-pair limit was confirmed from source, not a stress test. Body dynamics, other backends, images and performance were not tested.
Declarations checked against C# SDK 1.0.0. Expand a name to see declarations and documentation.
Properties1
CustomSolverBiasProperty
public float CustomSolverBias { get; set; }Custom contact-solver penetration-correction bias, initially 0. In the current 2D backend, 0 uses the space bias; two nonzero shape biases are averaged, while a single nonzero value is used directly. Not a margin, radius or overlap filter. The Inspector suggests 0…1; the setter neither clamps to this range nor emits Changed. Usually leave 0; effects on body dynamics were not tested in this run.
Methods8
Collidebool
public bool Collide(Transform2D localXform, Shape2D withShape, Transform2D shapeXform);Tests this shape against withShape at two supplied Transform2D values, without motion. Both transforms must map shape-local coordinates into one query space. Does not find world bodies, apply CollisionObject2D layers/masks or move an Entity. Requires an existing non-null second shape resource.
| Name | Type | Default |
|---|---|---|
localXform | Transform2D | — |
withShape | Shape2D | — |
shapeXform | Transform2D | — |
localXformTransform from this shape’s local coordinates into the common query space. A world-space query must include the shape user’s global transform and its local offset.
withShapeSecond existing non-null Shape2D resource with configured geometry. Not a CollisionObject2D or body RID.
shapeXformTransform from withShape-local coordinates into the same space as localXform. Not the second shape’s transform relative to the first.
booltrue when the two shapes overlap at the supplied transforms; otherwise false. Provides no body or contact normal.
CollideAndGetContactsVector2[]
public Vector2[] CollideAndGetContacts(Transform2D localXform, Shape2D withShape, Transform2D shapeXform);Returns a flat array of contact pairs for two shapes without motion: [A0,B0,A1,B1,…]. A belongs to this shape and B to withShape; both points are already in the supplied transforms’ common query space. No overlap returns an empty array. The current limit is 16 pairs (32 Vector2), not 16 elements. This is not a list of bodies, normals or all possible world contacts.
| Name | Type | Default |
|---|---|---|
localXform | Transform2D | — |
withShape | Shape2D | — |
shapeXform | Transform2D | — |
localXformTransform from this shape’s local coordinates into the common query space. A world-space query must include the shape user’s global transform and its local offset.
withShapeSecond existing non-null Shape2D resource with configured geometry. Not a CollisionObject2D or body RID.
shapeXformTransform from withShape-local coordinates into the same space as localXform. Not the second shape’s transform relative to the first.
Vector2[]Up to 16 point pairs [A0,B0,A1,B1,…] in query space, or an empty array. Pair count is Length/2.
CollideWithMotionbool
public bool CollideWithMotion(Transform2D localXform, Vector2 localMotion, Shape2D withShape, Transform2D shapeXform, Vector2 shapeMotion);Tests overlap with supplied displacement vectors for both shapes. Displacements use the common query space and are not velocities: delta is not applied automatically. For ordinary convex shapes, the SAT path compares swept geometric regions; true does not prove collision at the same instant. WorldBoundaryShape2D and SeparationRayShape2D use separate algorithms. Does not return a safe movement fraction, impact time, rotation during motion or body response.
| Name | Type | Default |
|---|---|---|
localXform | Transform2D | — |
localMotion | Vector2 | — |
withShape | Shape2D | — |
shapeXform | Transform2D | — |
shapeMotion | Vector2 | — |
localXformTransform from this shape’s local coordinates into the common query space. A world-space query must include the shape user’s global transform and its local offset.
localMotionThis shape’s displacement vector in common query space. If starting from velocity, compute displacement for the intended interval yourself. Vector2.Zero disables sweeping this shape.
withShapeSecond existing non-null Shape2D resource with configured geometry. Not a CollisionObject2D or body RID.
shapeXformTransform from withShape-local coordinates into the same space as localXform. Not the second shape’s transform relative to the first.
shapeMotionwithShape displacement in common query space; pass Vector2.Zero for a stationary second shape. Two displacements do not turn this into a synchronized time-of-impact calculation.
boolDisplacement-query result; the algorithm depends on shape types. true is not proof of simultaneous moving-body collision and contains no movement fraction.
CollideWithMotionAndGetContactsVector2[]
public Vector2[] CollideWithMotionAndGetContacts(Transform2D localXform, Vector2 localMotion, Shape2D withShape, Transform2D shapeXform, Vector2 shapeMotion);Returns displacement-query contact pairs as [A0,B0,A1,B1,…], up to 16 pairs. An empty array means no returned contacts. Coordinates use the common query space; these are displacement-query contacts, not a guaranteed first impact point on synchronized trajectories. CollideWithMotion limitations still apply; the array contains no impact time, Collider or safe movement fraction.
| Name | Type | Default |
|---|---|---|
localXform | Transform2D | — |
localMotion | Vector2 | — |
withShape | Shape2D | — |
shapeXform | Transform2D | — |
shapeMotion | Vector2 | — |
localXformTransform from this shape’s local coordinates into the common query space. A world-space query must include the shape user’s global transform and its local offset.
localMotionThis shape’s displacement vector in common query space. If starting from velocity, compute displacement for the intended interval yourself. Vector2.Zero disables sweeping this shape.
withShapeSecond existing non-null Shape2D resource with configured geometry. Not a CollisionObject2D or body RID.
shapeXformTransform from withShape-local coordinates into the same space as localXform. Not the second shape’s transform relative to the first.
shapeMotionwithShape displacement in common query space; pass Vector2.Zero for a stationary second shape. Two displacements do not turn this into a synchronized time-of-impact calculation.
Vector2[]Up to 16 displacement-query point pairs in query space, or an empty array; no impact time or safe movement fraction.
Drawvoid
public void Draw(Rid canvasItem, Color color);Adds concrete-shape drawing commands to an existing CanvasItem RID using the supplied color. Creates no CanvasItem, physics body or material. Intended for diagnostic 2D drawing; repeated calls append commands and the CanvasItem owner controls clearing. Command submission was checked headlessly, not appearance, antialiasing or image quality.
| Name | Type | Default |
|---|---|---|
canvasItem | Rid | — |
color | Color | — |
canvasItemValid CanvasItem RID. Ownership and command clearing remain with the caller; do not pass a shape or body RID.
colorDiagnostic shape color, including alpha. Does not affect physics geometry.
GetCustomSolverBiasfloat
public float GetCustomSolverBias();Returns this shape’s stored custom bias; 0 means use the space bias, not disable correction. Does not return the final averaged value for a body pair.
floatThis shape’s stored bias, initially 0; not the final bias for a pair.
GetRectRect2
public Rect2 GetRect();Returns the local Rect2 defined by the concrete shape; Entity position/rotation and previously supplied query transforms are excluded. Circle, rectangle and capsule return geometric bounds. Do not use this as an exact collision test: a contour may be hollow, SeparationRayShape2D adds debug-drawing padding, and WorldBoundaryShape2D’s finite rectangle does not bound its infinite physical boundary.
Rect2Rectangle in the concrete shape’s local coordinates; neither world bounds nor an exact overlap result.
SetCustomSolverBiasvoid
public void SetCustomSolverBias(float bias);Custom contact-solver penetration-correction bias, initially 0. In the current 2D backend, 0 uses the space bias; two nonzero shape biases are averaged, while a single nonzero value is used directly. Not a margin, radius or overlap filter. The Inspector suggests 0…1; the setter neither clamps to this range nor emits Changed. Usually leave 0; effects on body dynamics were not tested in this run.
| Name | Type | Default |
|---|---|---|
bias | float | — |
biasCustom solver bias; normally 0 to use the space setting. The Inspector’s 0…1 range is not enforced as a setter clamp.