Movement
Overview
The MovementSystem
provides a way to move an entity on surfaces with various parameters at different speeds. Movement inputs in the form of MovementDesires
and external forces such as gravity or jump impulse are processed by a custom acceleration & friction based kinematic character controller (abbreviated KCC). The KCC calculates the movement delta taking into consideration the results from physics collision hits (raycasts/shape overlaps) and applies the resulting values to the entity's Transform3D
.
N.B.: The KCC included in the FPS Template is a completely custom implementation and different from the 2D and 3D KCCs included in the default Quantum SDK.
FSM
The movement engine is a finite state machine. The supported states are implemented in EMovementState
.
Idle
: character stands AND is grounded, no forces are applied.Moving
: character moves AND is grounded, input and external forces are applied.Jumping
: special state when moving up after a jump, the character is not grounded.Falling
: character moves downwards (also after jump Y velocity below 0), character is not grounded.Sliding
: character stands or move on a sloped surface AND is grounded.Rising
: moving up as a result of external force ( not jumping), character is not grounded.Floating
: special state to move with specific force, ignores gravity.
API
The API provided to make movement calculations are:
ResetVelocity()
: resets current movement velocity.AddForce()
: applies a force next timeUpdate()
is called. The final delta velocity calculation is affected by the internal state (surface, slope, ...). This should be called to apply a force which lasts over a period of time.AddImpulse()
: applies a force impulse next timeUpdate()
is called. The final delta velocity calculation is affected by internal state (surface, slope, ...). This should be called to apply one-time impulses.AddVelocity()
: applies a raw delta velocity next timeUpdate()
is called. This does not affected the internal state (surface, slope, ...).Teleport()
: requests teleport to a specific position. It is executed next timeUpdate()
is called.SetFloating()
: puts entity into theFloating
state. This has to be called every frame for whole duration of the state.
Collisions
By default, the KCC movement ignores the entity's own body parts and does not collide with triggers colliders. It is possible to add custom collision resolution by implementing the IMovementController
interface.
Static Quantum Colliders can hold surface properties; these are defined in a ColliderConfig
asset which then needs to be linked to a static collider's Settings > User
asset slot.
Execution Flow
The following diagram presents a rough overview of the MovementSystem
's logic execution flow.