Physics · class

CharacterController

Explained in Your first game, Rigid bodies.

class CharacterController
import { CharacterController } from '@driftengine/physics';

Constructor

new

constructor(options?: ControllerOptions)
ParameterTypeDescription
options?ControllerOptions

Properties

NameTypeDescription
xnumber
ynumber
znumber
velXnumber
velYnumber
velZnumber
stateControllerState
groundXnumberThe surface normal under the feet, meaningful when grounded or sliding.
groundYnumber
groundZnumber
upXnumberWhich way is up for this body, as a unit vector. World up unless a caller says otherwise.
More

The whole of this class used to assume one axis, and none of it was wrong for doing so. velY was the only representation of vertical velocity, gravity was a scalar applied to it, slopeCos was measured against world Y, stepHeight was a height only because up was fixed, and the three states were decided by a downward probe. That is a complete and correct controller for a body on a floor, and it cannot represent one on a wall at all.

A consumer needing one had to reimplement the sweep, the step-over, the slope test and the ground probe — roughly nine hundred lines that would not share this file's contact code, so the two would drift. It is not a gecko's problem: it is every wall-crawler, every arbitrary-gravity level and every walker on the inside of a rotating station.

Settable per tick, because a body walking around a corner changes frame continuously and the alternative is rebuilding the controller. Read through setUp, which normalises, so the dot products below can assume unit length.

upYnumber
upZnumber
groundBodynumberWhich body is being stood on, or −1.
shapereadonlyConvexShape
radiusreadonlynumber
halfHeightreadonlynumber
stepHeightreadonlynumber
slopeCosreadonlynumber
maxSpeedreadonlynumber
accelerationreadonlynumber
decelerationreadonlynumber
airControlreadonlynumber
jumpSpeedreadonlynumber
jumpCutoffreadonlynumber
gravityreadonlynumber
coyoteTicksreadonlynumber
jumpBufferTicksreadonlynumber
slideBoostreadonlynumber
pushStrengthreadonlynumber
filterreadonlyQueryFilter | undefined

Accessors

NameTypeDescription
speedAlongUpgetnumberThis body's speed along its own up. What velY was when up was always world Y.

Methods

setUp

setUp(x: number, y: number, z: number): void

Point this body's up at a direction, normalising it.

ParameterTypeDescription
xnumber
ynumber
znumber
More

A zero-length vector is refused rather than normalised into a NaN frame, because every dot product below would then answer NaN and the states would read as a body that is nowhere. It keeps the frame it had, which is the defined state the two-backends rule asks for in the renderer and is the right answer here for the same reason.

setGravityDirection

setGravityDirection(x: number, y: number, z: number): void

Point the fall direction somewhere other than up, and stop it following.

ParameterTypeDescription
xnumber
ynumber
znumber
More

The sign convention is up's: gravity is negative, so this is the direction a rise goes and gravity is applied against it. That is the same arithmetic as before — velY += gravity * dt with a gravity of −20 is an acceleration along −Y — generalised rather than reversed.

teleport

teleport(x: number, y: number, z: number): void

Place the character, clearing whatever it was doing.

ParameterTypeDescription
xnumber
ynumber
znumber

move

move(world: PhysicsWorld, dt: number, input: ControllerInput): void

Advance one fixed tick.

ParameterTypeDescription
worldPhysicsWorld
dtnumber
inputControllerInput