A character controller is a special type of physics body that uses its own collision resolution which is geared for user-controlled characters. Use a character controller for an entity that you can consider kinematic (i.e. controlled by user inputs, not affected by forces like gravity), but is also your main playable character. A character controller will benefit from continuous collision detection and its own collision resolution algorithm that has been tweaked to provide a good feeling while controlling the player.
To make your entity a character controller it needs the following components:
Character Controller
Entity Component
Character Controller character_controller
Kinematic character controller for collision-constrained movement without a rigid body. Uses tuned collision handling for responsive control.
Schema
skinWidth
Float(m)
Default:0
Collision skin width (meters).
Collision skin width (meters).
slopeLimit
Float(deg)
Default:45
Maximum walkable slope (degrees). Slopes steeper than this are not walkable.
Maximum walkable slope (degrees). Slopes steeper than this are not walkable.
stepOffset
Float(m)
Default:0
Maximum climbable step height. Steps higher than this cannot be climbed automatically.
Maximum climbable step height. Steps higher than this cannot be climbed automatically.
Physics Material
Entity Component
Physics Material physics_material
Physical surface properties used for contact: friction, restitution, optional contact modification, and trigger mode.
Schema
contactVelocity
Vector3(m/s)
Default:[0,0,0]
Applied contact velocity offset when colliding (m/s). Only used if modifyContact is true.
Applied contact velocity offset when colliding (m/s). Only used if modifyContact is true.
dynamicFriction
Float
Default:0.5
Dynamic (kinetic) friction coefficient (typically 0..1). If greater than staticFriction, staticFriction is clamped up to match. Effective value is averaged with the other surface.
Dynamic (kinetic) friction coefficient (typically 0..1). If greater than staticFriction, staticFriction is clamped up to match. Effective value is averaged with the other surface.
isTrigger
Boolean
Default:false
Treat associated geometry as a trigger (generates events but no physical response).
Treat associated geometry as a trigger (generates events but no physical response).
modifyContact
Boolean
Default:false
Enable contact modification (applies contactVelocity on collisions).
Enable contact modification (applies contactVelocity on collisions).
restitution
Float
Default:0
Restitution (bounciness) in [0,1]. 0 = no bounce; 1 = perfectly elastic. Effective value is averaged with the other surface.
Restitution (bounciness) in [0,1]. 0 = no bounce; 1 = perfectly elastic. Effective value is averaged with the other surface.
staticFriction
Float
Default:0.5
Static friction coefficient (typically 0..1). 0 feels like ice; higher resists start of motion. Effective value is averaged with the other surface.
Static friction coefficient (typically 0..1). 0 feels like ice; higher resists start of motion. Effective value is averaged with the other surface.
one geometry component from this list:
Capsule Geometry
Entity Component
Capsule Geometry capsule_geometry
Capsule geometry.
Schema
axis
Integer
Default:1(Y-Axis)
Alignment axis of the capsule: 0=X, 1=Y, 2=Z.
0X-Axis1Y-Axis2Z-Axis
Alignment axis of the capsule: 0=X, 1=Y, 2=Z.
height
Float(m)
Default:1
Height of the cylindrical mid‑section (meters).
Height of the cylindrical mid‑section (meters).
offset
Vector3(m)
Default:[0,0,0]
Local offset of the geometry origin (meters).
Local offset of the geometry origin (meters).
radius
Float(m)
Default:0.5
Radius of the hemispherical ends (meters).
Radius of the hemispherical ends (meters).
,
Box Geometry
Entity Component
Box Geometry box_geometry
Box geometry.
Schema
dimension
Vector3(m)
Default:[1,1,1]
Box dimensions (width, height, depth) in meters.
Box dimensions (width, height, depth) in meters.
offset
Vector3(m)
Default:[0,0,0]
Local offset of the geometry origin (meters).
Local offset of the geometry origin (meters).
Between the two, the capsule geometry is the recommended default choice.
There’s a slight caveat with the box character controller. Unlike other bodies, the box geometry of a character controller will NOT be affected by the orientation of your entity. The box always has a fixed rotation even when the player is (visually) rotating.
However, the capsule character controller will be impacted by the orientation of your entity. The orientation of your entity will be multiplied to the axis vector of your capsule, which will decide the capsule’s orientation.
The character controller is moved by affecting its displacement in the character controller component. The displacement attribute in the character controller is an engine-only attribute, and so is not viewable in the editor, but is accessible in scripts. The physics engine will try to move the character controller by the displacement, and do any collision resolution if necessary. The displacement you input will be used to move the character only for that frame; you need to keep updating the displacement each frame you want to keep moving it.
If you need help setting this up, please join our discord.