Babylon.js Physics Engine — Realistic Movement and Collisions
In this tutorial, you will learn about Babylon.js Physics Engine. We cover key concepts, practical examples, and best practices to help you master this topic.
Babylon.js physics engine adds realistic rigid body dynamics, collisions, and forces to 3D scenes using Havok, Ammo.js, or Cannon.js backends.
What You'll Learn
By the end of this guide, you will enable the physics engine, create rigid bodies for meshes, apply forces and impulses, detect collision events, create joints and constraints, and build physical simulations.
Enable Physics
var physicsHelper = new BABYLON.PhysicsHelper(scene);
var physicsEngine = physicsHelper.setPhysicsEngine(BABYLON.PhysicsEngine.HavokPlugin, {
gravity: new BABYLON.Vector3(0, -9.81, 0)
});
Rigid Body
var box = BABYLON.MeshBuilder.CreateBox('box', { size: 1 }, scene);
box.position.y = 5;
var boxAggregate = new BABYLON.PhysicsAggregate(box, BABYLON.PhysicsShapeType.BOX, {
mass: 1,
restitution: 0.5,
friction: 0.3
}, scene);
Ground as Static Body
var ground = BABYLON.MeshBuilder.CreateGround('ground', { width: 10, height: 10 }, scene);
var groundAggregate = new BABYLON.PhysicsAggregate(ground, BABYLON.PhysicsShapeType.BOX, {
mass: 0 // Static
}, scene);
Apply Force
boxAggregate.body.applyForce(
new BABYLON.Vector3(0, 10, 0),
box.getAbsolutePosition()
);
Collision Events
boxAggregate.body.onCollisionEndedObservable.add(function(collider) {
if (collider === groundAggregate.body) {
console.log('Box hit the ground');
}
});
Common Mistakes
1. Physics Engine Not Installed
Babylon.js physics plugins are separate packages. Import the Havok plugin file.
2. Mass Zero Makes Static
Set mass = 0 for static bodies (ground, walls). Dynamic bodies need mass > 0.
3. Wrong Shape Type
Use PhysicsShapeType for the aggregate: BOX, SPHERE, CAPSULE, CONVEX_HULL, etc.
4. Physics Update Not Running
The physics engine auto-steps with the render loop. Ensure engine.runRenderLoop is running.
5. Scale Affecting Physics
Non-uniform scale on meshes with physics aggregates causes incorrect collision shapes.
Practice Questions
Q1: What physics backends does Babylon.js support? A: Havok (recommended), Ammo.js, Cannon.js.
Q2: How do you make a physics body static? A: Set mass = 0 in the PhysicsAggregate options.
Q3: How do you apply an impulse? A: Call body.applyImpulse(impulseVector, contactPoint) on the PhysicsBody.
Q4: How do you detect collision? A: Subscribe to body.onCollisionEndedObservable or onCollisionStartedObservable.
Q5: How do you remove a physics body? A: Dispose the PhysicsAggregate: aggregate.dispose().
Challenge: Build a bowling ball launcher with pins. The ball should be launched with a force based on a power meter. Pins should scatter on impact.
FAQ
Try It Yourself
Build a falling ball physics demo.
<!DOCTYPE html>
<html>
<head>
<title>Babylon.js Physics</title>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/collections/havok.js"></script>
</head>
<body style="font-family:sans-serif;padding:20px;">
<h2>Physics Demo</h2>
<button onclick="dropBox()">Drop Box</button>
<canvas id="renderCanvas" style="width:100%;height:400px;border-radius:8px;"></canvas>
<script>
var canvas = document.getElementById('renderCanvas');
var engine = new BABYLON.Engine(canvas, true);
var scene = new BABYLON.Scene(engine);
var camera = new BABYLON.ArcRotateCamera('camera', -Math.PI/2, Math.PI/3, 10, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, true);
new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0, 1, 0), scene);
var ground = BABYLON.MeshBuilder.CreateGround('ground', { width: 10, height: 10 }, scene);
// Initialize Havok physics
var havokInstance = HavokPhysics();
var hk = new BABYLON.HavokPlugin(true, havokInstance);
scene.enablePhysics(new BABYLON.Vector3(0, -9.81, 0), hk);
var groundAggregate = new BABYLON.PhysicsAggregate(ground, BABYLON.PhysicsShapeType.BOX, { mass: 0 }, scene);
function dropBox() {
var box = BABYLON.MeshBuilder.CreateBox('box', { size: 0.5 }, scene);
box.position.x = Math.random() * 4 - 2;
box.position.y = 5;
box.position.z = Math.random() * 4 - 2;
var mat = new BABYLON.StandardMaterial('mat', scene);
mat.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random());
box.material = mat;
new BABYLON.PhysicsAggregate(box, BABYLON.PhysicsShapeType.BOX, {
mass: 1,
restitution: 0.3 + Math.random() * 0.5
}, scene);
}
engine.runRenderLoop(function() { scene.render(); });
window.addEventListener('resize', function() { engine.resize(); });
</script>
</body>
</html>
What's Next
Add spatial audio.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro