Character Controller

Cocos Creator supports character controllers since v3.8.

The character controllers provide a simple way to add a character controller to your game.

Add Character Controller

There are two types of character controllers in Cocos Creator, box character controller, and capsule character controller, both of them are inherited from the base class CharacterController.

It is recommended that character controllers are invalid only in the Bullet and PhysX backends. By clicking on the Project menu, open the Project Setting panel, and find Physics System in the Feature Cropping page, choose Bullet or PhysX in the drop-down menu.


Common Properties

The following properties are the common properties of the character controller which can be found in the Inspector panel of Box Character Controller and Capsule Character Controller component.

Properties Description
Group Physics group,refer to Collision Matrix for more details.
Min Move Distance The minimum movement distance of the character controller. If the move distance invoked by the move method is smaller than this value, the character controller will not move.
Center The center of the character controller in local space
Step Offset The maximum height the character controller can automatically climb.
Slope Limit The slope limit of the character controller in degrees.
Skin Width The skin width of the character controller, please see below for more details

Capsule Character Controller

By clicking the Add Component button in the Inspector panel add a CapsuleCharacterController.




Properties Description
Radius The radius of the sphere of the capsule shape of the CharacterController in local space
Height The distance between the center of two half-sphere

Box Character Controller

By clicking the Add Component button in the Inspector panel to add a BoxCharacterController.




Properties Description
Half Height The half height of the box shape of the CharacterController in local space
Half Side Extent The half-side extent of the box shape of the CharacterController in local space
Half Forward Extent The half-forward extent of the box on the CharacterController in local space

Manipulating the Character Controllers

To drive a character controller to move, you can use the move method with the following code.

const movement = v3(1.0, 0, 0);
let characterController = this.node.getComponent(CharacterController);

The move method which uses the algorithm of the sweep method as its internal takes into all the colliders on its path. On the one hand, it will judge the angle between the character controller and the collider, if it is smaller than the slope limit, the character controller will continue to walk along the surface of the collider, on the other hand, if the height difference between the character controller and the collider is smaller than the step offset, the character controller also automatically climbing the step. But if the two conditions above are not satisfied, the controller will stop.

To reset the position of a character controller, use the setPosition method of the character controller instead of using setPosition of the node, as follows.

let characterController = this.node.getComponent(CharacterController);
characterController.setPosition(new Vec3(-3,5,6));

When a character controller node is moved via the setPosition method, it will automatically set the position of the physics world simultaneously, however, the setPosition or setWorldPosition method of the node may cause the scene and physics world position out of sync.

That is because when every frame when the synchronization of the position from the render scene to the physics world, the center offset must be taken into consideration.

It can be noticed that the Character Controller applies no force like gravity by default, developers need to add custom forces or change the velocity to simulate the movement or rotation.

Determine if on the Ground

Use the isGrounded method to determine whether a character controller is standing on some colliders with the following code.

let characterController = this.node.getComponent(CharacterController);
const isOnGround = characterController.isGrounded;

Collision Callback

The onColliderHit event will be emitted when a collision occurs between the character controller and the collider, the code example is as follows.

let characterController = this.node.getComponent(CharacterController)!;
characterController.on('onControllerColliderHit', this.onColliderHit, this);

The callback of the collision is declared as follows:

onColliderHit (contact: CharacterControllerContact){}

The description of the callback is below.


Normally a character is not a fully simulated physics object when we try to simulate a character, which means it will not exhibit full physics characteristics. This means that when the collision occurs, the force situation of the character controller is different from a dynamic rigid body. Changing the position, or simulating velocity in the collision callback to implement the fore effect.

To simulate the full physics effect, please use Dynamic Rigibody. Note that if you attach a rigid body component to the node containing a character controller, this may cause unexpected errors which normally we do not recommend.

There is no physics effect between character controllers, and this feature will be added in the future version.

Skin Width

The Skin Width property allows slight penetration between a character controller and a collider to avoid shaking or stuck.

It is usually a small, floating number above zero.

If stuck frequently, you can adjust the Skin Width to a large number to avoid precision problems with floating-point numbers.


The address of the character controller is GIT. Import the project, and run the case-character-controller.scene scene to see the character controller example.


For the API of the character controller, please refer to Character Controller, Box Character Controller and Capsule Character Controller.


The character controller is not supported on ByteDance mini-game wasm. Use the builtin wasm in Cocos Creator to enable this feature.

results matching ""

    No results matching ""