It’s that time of year again! Release prep time! Yup that’s right! Babylon.js 9.0 is currently scheduled to release at the end of March!
That means it’s time to start the process of pulling together the Babylon 9.0 release video!
Every year, the big annual release is the biggest marketing moment of the year. We celebrate each release with a special “announcement video” for the new version of Babylon. We try our best to make these videos big, bold, and exciting and we want you to be a part of it!
Each one of you is an important part of this community and we like to take this moment once a year to show you how much we appreciate you and what you create with Babylon.js, by including some of your Babylon.js creations in the release video.
If you have made something with Babylon in the last year, then you can submit your creation to be considered by simply replying to this thread with a link to something you’ve made with Babylon.js.
The submission deadline is Friday Feb 27th 2026!
Please note that due to the length of these videos (2-3 mins) and the number of submissions, we may not be able to include every submission in the video.
Check out last year’s release video to see where/how community submissions are featured!
Can’t wait to include your amazing work in the video this year!
I’m happy to annouce the availability of the Physics Character Controller.
It provides a simple api to control and extent a character in a physicalized world.
Great work! Just looking at the controller part: does this want to have it’s own class/separate it because I’m understanding this code actually as a “PhysicsCharacter”. As it could be controlled by a Player or AI right? Plus I couldn’t see any controller related code (I’m using my phone). The Controller part I usually define as the interface for the Player or AI.
Hi, could you please modify the example to include rotation functionality? Specifically, I’d like the player to rotate when pressing A/D keys, always face the forward direction, and also rotate while jumping. Thank you!
Hey @Cedric … Can you please explain a bit about how you use the character controller. It seems a bit different than how you would use btKinematicCharacterController for example.
getDesiredVelocity … That seems to be doing alot of stuff. Where as before you might just do a inputVector.normalized*speed and the that was your movement velocity you used. I think moveWithCollisions worked that way as well.
I am trying to replace my RigidBody based character controller i wrote that worked like the Ammo btKinematicCharacterController with the new BABYLON.PhysicsCharacterController underneath my ThirdPersonCharacterController, but I am having trouble understanding all this, and how i can use this in place of my Unity Style Character controller I was using with Ammo.js
// State handling
// depending on character state and support, set the new state
var getNextState = function(supportInfo) {
if (state == "IN_AIR") {
if (supportInfo.supportedState == BABYLON.CharacterSupportedState.SUPPORTED) {
return "ON_GROUND";
}
return "IN_AIR";
} else if (state == "ON_GROUND") {
if (supportInfo.supportedState != BABYLON.CharacterSupportedState.SUPPORTED) {
return "IN_AIR";
}
if (wantJump) {
return "START_JUMP";
}
return "ON_GROUND";
} else if (state == "START_JUMP") {
return "IN_AIR";
}
}
// From aiming direction and state, compute a desired velocity
// That velocity depends on current state (in air, on ground, jumping, ...) and surface properties
var getDesiredVelocity = function(deltaTime, supportInfo, characterOrientation, currentVelocity) {
let nextState = getNextState(supportInfo);
if (nextState != state) {
state = nextState;
}
let upWorld = characterGravity.normalizeToNew();
upWorld.scaleInPlace(-1.0);
let forwardWorld = forwardLocalSpace.applyRotationQuaternion(characterOrientation);
if (state == "IN_AIR") {
let desiredVelocity = inputDirection.scale(inAirSpeed).applyRotationQuaternion(characterOrientation);
let outputVelocity = characterController.calculateMovement(deltaTime, forwardWorld, upWorld, currentVelocity, BABYLON.Vector3.ZeroReadOnly, desiredVelocity, upWorld);
// Restore to original vertical component
outputVelocity.addInPlace(upWorld.scale(-outputVelocity.dot(upWorld)));
outputVelocity.addInPlace(upWorld.scale(currentVelocity.dot(upWorld)));
// Add gravity
outputVelocity.addInPlace(characterGravity.scale(deltaTime));
return outputVelocity;
} else if (state == "ON_GROUND") {
// Move character relative to the surface we're standing on
// Correct input velocity to apply instantly any changes in the velocity of the standing surface and this way
// avoid artifacts caused by filtering of the output velocity when standing on moving objects.
let desiredVelocity = inputDirection.scale(onGroundSpeed).applyRotationQuaternion(characterOrientation);
let outputVelocity = characterController.calculateMovement(deltaTime, forwardWorld, supportInfo.averageSurfaceNormal, currentVelocity, supportInfo.averageSurfaceVelocity, desiredVelocity, upWorld);
// Horizontal projection
{
outputVelocity.subtractInPlace(supportInfo.averageSurfaceVelocity);
let inv1k = 1e-3;
if (outputVelocity.dot(upWorld) > inv1k) {
let velLen = outputVelocity.length();
outputVelocity.normalizeFromLength(velLen);
// Get the desired length in the horizontal direction
let horizLen = velLen / supportInfo.averageSurfaceNormal.dot(upWorld);
// Re project the velocity onto the horizontal plane
let c = supportInfo.averageSurfaceNormal.cross(outputVelocity);
outputVelocity = c.cross(upWorld);
outputVelocity.scaleInPlace(horizLen);
}
outputVelocity.addInPlace(supportInfo.averageSurfaceVelocity);
return outputVelocity;
}
} else if (state == "START_JUMP") {
let u = Math.sqrt(2 * characterGravity.length() * jumpHeight);
let curRelVel = currentVelocity.dot(upWorld);
return currentVelocity.add(upWorld.scale(u - curRelVel));
}
return Vector3.Zero();
}
// Display tick update: compute new camera position/target, update the capsule for the character display
scene.onBeforeRenderObservable.add((scene) => {
displayCapsule.position.copyFrom(characterController.getPosition());
// camera following
var cameraDirection = camera.getDirection(new BABYLON.Vector3(0,0,1));
cameraDirection.y = 0;
cameraDirection.normalize();
camera.setTarget(BABYLON.Vector3.Lerp(camera.getTarget(), displayCapsule.position, 0.1));
var dist = BABYLON.Vector3.Distance(camera.position, displayCapsule.position);
const amount = (Math.min(dist - 6, 0) + Math.max(dist - 9, 0)) * 0.04;
cameraDirection.scaleAndAddToRef(amount, camera.position);
camera.position.y += (displayCapsule.position.y + 2 - camera.position.y) * 0.04;
});
The new character controller gives a lot of control but user has to take care of state machine.
To replace the previous Ammo, I would not care about the state machine and just call calculateMovement with appropriate parameters.
How do we set or change the current position of the physics based character.
In other character controller system, we had the teleport or someway of overriding and setting the position of the physics based character. I dont see an easy way to set the position beside the initial character position in the constructor.
Also… There is alot of easing and the character still keeps moving after you stop. Can we control how much easing so it does not keep moving so much? Its hard to sync the character animations with all that extra easing in the movement.
For the easing, you can use accelerationBabylon.js docs and maxAccelerationBabylon.js docs
Let me do some tests for the teleport. I don’t remember testing that. It might be missing
the character position is set to ground position with 0.3 height. That is the floor height. when you do anything that makes that character rise higher, like traversing stairs or even just jumping, it never goes back (gravity) to the floor height of 0.3. like the contact or internal raycast or what ever is not fulling grounding the player character. Sometimes you jump and land and the character is at position.y = 0.33 or 0.32 or 0.28… but almost never back to the ground position of 0.3.
The big problem for me, is when I stick a player skeletal mesh in the player character and his feet are perfectly aligned on the ground at 0.3 floor height. After jumping it may seem like the character is floating when above 0.3 floor. height or even sunk into the floor when less than floor height.
Is there any anything we can set to make the collision detection with the ground more precise ?