API

Physics character controller

What is it

A character controller is a specialized component designed to manage the movement and interactions of a character within a game world. Conceptually, it resides between the game/experiment code and the physics engine.

Creating a Controller

Users can either create and provide a physics shape to the controller or let it create a capsule by providing its dimensions.

import { Vector3 } from "@babylonjs/core/Maths/math.vector";
import { MeshBuilder } from "@babylonjs/core/Meshes/meshBuilder";
import { PhysicsCharacterController } from "@babylonjs/core/Physics/v2/characterController";
let h = 1.8;
let r = 0.6;
let displayCapsule = MeshBuilder.CreateCapsule("CharacterDisplay", { height: h, radius: r }, scene);
let characterPosition = new Vector3(3, 0.3, -8);
let characterController = new PhysicsCharacterController(characterPosition, { capsuleHeight: h, capsuleRadius: r }, scene);

moveWithCollisions

moveWithCollisions is a synchronous function that moves the character to the target position while taking care of collisions along the way.

Character Controller moveWithCollisions

Kinematic platforms

Physics bodies of PhysicsMotionType.ANIMATED can interact with the character. This allows the creation of lifts, platforms, and more.

Character Controller animated platform

Observable

The custom collision observable lets you get collision information specific to the character controller.

characterController.onTriggerCollisionObservable.add((event)=>{
console.log(`Character collision : ${event.collider.transformNode.name} at ${event.impulsePosition.toString()} `);
});

Here, the event type is ICharacterControllerCollisionEvent and it contains information about the collider, position, and impulse.

Character Controller collision observer

The loop

There are 3 major steps:

  • Getting the support: on what surface the character is
  • Setting the desired velocity: what the character's velocity is based on its properties and state
  • Tick update on the controller

Then, it's possible to get the character position using characterController.getPosition() and set a skinned mesh position, for example.

In the following example, velocity is a function of the character state. That state can be START_JUMP, IN_AIR, or ON_GROUND. These different steps allow for different behaviors and movement speeds. Depending on user needs, it's possible to have speed and velocity control for swimming, for example.

The main loop can be summarized with these calls:

const support = characterController.checkSupport(dt, down);
const desiredLinearVelocity = getDesiredVelocity(dt, support, characterCurrentOrientation, characterCurrentVelocity);
characterController.setVelocity(desiredLinearVelocity);
characterController.integrate(dt, support, characterGravity);
const newPosition = characterController.getPosition();

The test room PG provides an example to compute the desired velocity based on a finite state.

Character Controller testing room

Further reading

Performance Tips
A guide on best practices to achieve maximum performance with the Physics V2 API
Performance Tips