Collision
Overlap, then a slide. Nothing is pushed apart.
Collision is in WillEngine.Core.Collision. Units are world pixels, Y grows downward. There is no solver: colliders detect overlap, Move slides a mover along solids, and queries ask the scene. Two overlapping bodies stay overlapping until your code moves one.
Colliders join their scene’s collision world on OnEnabled and leave it on OnDisabled. Outside Play, Move only translates, and touching queries are false.
Shapes
Add BoxCollider, CircleCollider, PointCollider, or MaskCollider. They share:
Name— which collider of an object a contact is talking about. Defaults are Box, Circle, Point, and Mask.Layer— 0 through 31. The Inspector shows the name fromcollision.json.Offset— center relative to the object, multiplied by world scale.IsStatic— walls and ground. Checked against movers only. Two static colliders never collide.
Each collider has Entered, Staying, and Exited events with a Contact, plus IsTouching() for any contact or for one layer. Staying is dispatched only when something is listening.
Layers
Layers and which pairs meet are project data in Project/collision.json, edited as named layers. A mover tests the layers its own layer is set to meet. Mark floors and walls static on their own layer so characters pay for the test and the scenery does not test itself.
Move
Move(dx, dy) moves the whole object by world pixels, X then Y, sliding along solids on every layer this collider meets. The overload takes a layer bitmask and stepUp: when a sideways move is blocked, the body is lifted up to that many pixels to climb a bump. MoveResult reports how far it actually moved, which side it hit (HitBelow means standing on something), and whether it stepped up. Move itself does not raise collision events. Call it from OnUpdate with deltaTime so speed is in pixels per second.
using WillEngine.Core.Collision;
using WillEngine.Core.Components;
using WillEngine.Core.Controls;
public class Walker : Component
{
public override void OnUpdate(float dt)
{
var box = Owner.GetComponent<BoxCollider>();
float dx = 0f;
if (Input.IsDown(Key.Left)) dx -= 80f * dt;
if (Input.IsDown(Key.Right)) dx += 80f * dt;
box.Move(dx, 0f);
}
}
Queries that should not move the body go through Owner.Scene.Collision: OverlapPoint, OverlapBox, OverlapCircle, and Raycast. A MaskCollider collides with the visible pixels of a sprite (or a sprite GUID you set), for irregular ground. Two masks never test each other.