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:

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.