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.