Raycast based physics motor

After playing around with Unity physics and seeing some control issues (BoxCollider's getting stuck on flat surfaces while moving), I decided to spend some time writing a different style of character controller and motor setup, and the RaycastingPhysicsMotor was born.

RaycastingPhysicsMotor objects work in a limited fashion much like a RigidBody2D, it controls its own velocity, handles gravity and collides with objects on its selected LayerMasks.

Every movement frame the object projects rays from the center of its BoxCollider2D in the 4 cardinal directions, the length of which is equivalent to the distance the object will travel in this frame + collider size + small offset (raycasting from an internal position is to detect intersection better) . If a collision is detected the object modifies its ⃗v to stop at the collision point.


Visualising raycasts and collisions between 2 objects

The motor handles collisions and movement as you would expect, horizontal and vertical collisions are blocking, causing velocity ⃗v to be capped as above. There are, however, 2 exceptions to this, ramps and one way platforms.

Ramps are solved using the surface normal of the collision surface, a threshold value (max slope angle), trigonometry and kinematics. Using secondary Layer Masks the component can also be flagged to allow travel through some objects in a specific direction (one way wall/platform).

The motor is instructed to move externally by a separate controller using its IPhysicsMovable interface. This allows the use of different motor implementations without the need to write separate code in the controller. If a GameObject has one of these, you can move it regardless of whether its a platform, an entity or a bullet.

Its important to note, that RaycastingPhysicsMotor provides collision physics and collision detection (exposing its collision state via struct), but does not inherently apply physics forces to other objects, this is a possible point of improvement should it be needed for this game.