Getting Started
PlayCanvas physics is powered by ammo.js, a port of the open source Bullet physics engine to WebAssembly. Once it is loaded, you build a simulation out of entities that carry a rigidbody component, which decides how the entity moves, and a collision component, which gives it a shape. This page covers loading the library, the global settings, and the rules that every other page in this section builds on.
Enabling Physics
Physics is opt-in. ammo.js weighs in at several hundred kilobytes, so nothing loads it unless you ask. It is distributed as three files: the WebAssembly module ammo.wasm.wasm, its JavaScript glue ammo.wasm.js, and ammo.js, an asm.js fallback for browsers without WebAssembly support. Until the library is present, physics components are inert placeholders: adding them does nothing and raises no errors.
- Engine
- Editor
- React
- Web Components
Load the module before creating the application. The three files ship with the engine repository under examples/assets/wasm/ammo/ and in the sync-ammo npm package.
pc.WasmModule.setConfig('Ammo', {
glueUrl: 'ammo/ammo.wasm.js',
wasmUrl: 'ammo/ammo.wasm.wasm',
fallbackUrl: 'ammo/ammo.js'
});
// Wait for the module, then create the application as usual
await new Promise((resolve) => {
pc.WasmModule.getInstance('Ammo', () => resolve());
});
const app = new pc.Application(canvas);
The rigid body system finds the Ammo global as the application starts and installs the ammo.js backend. pc.Application registers every component system for you; if you build from pc.AppBase and pc.AppOptions instead, add pc.CollisionComponentSystem and pc.RigidBodyComponentSystem (and pc.JointComponentSystem for joints) to componentSystems. The Falling Shapes example shows the complete sequence.
Open the Scene Settings panel, expand PHYSICS and click IMPORT AMMO. This adds the three files from the PlayCanvas Store to your assets, and the engine loads them before your scene starts.
Until the library is imported, the Collision and Rigid Body component inspectors show an Ammo module not found warning with the same button. To use your own build of ammo.js, add it as a WASM module asset instead of the Store version.
Projects created before ammo.js was distributed as module assets used a legacy copy of the library that the launcher injected automatically. If a project has no ammo.js assets but physics still works, this is why. Clicking IMPORT AMMO adds the module assets and turns the legacy library off at the same time, so a project never loads both. The imported build is newer, smaller and faster, so make the switch when you can.
Install the module and set the usePhysics prop on your root <Application>:
npm install sync-ammo
import { Application } from '@playcanvas/react';
<Application usePhysics>
{/* entities with <RigidBody> and <Collision> components */}
</Application>
ammo.js is loaded lazily when usePhysics is set, so your scene renders before the library arrives and physics components activate once it has. The usePhysics hook reports isPhysicsLoaded if you need to wait for that moment. See the React physics guide for details.
Declare the module with a <pc-wasm> tag inside <pc-app>:
<pc-app>
<pc-wasm name="Ammo"
glue="https://developer.playcanvas.com/assets/modules/ammo/ammo.wasm.js"
wasm="https://developer.playcanvas.com/assets/modules/ammo/ammo.wasm.wasm"
fallback="https://developer.playcanvas.com/assets/modules/ammo/ammo.js"></pc-wasm>
<pc-scene>
<!-- entities with <pc-rigid-body> and <pc-collision> components -->
</pc-scene>
</pc-app>
The application waits for the module before it starts, so every physics tag in the scene works from the first frame.
Gravity
Gravity is a constant acceleration applied to every dynamic rigid body. The default of -9.81 along the world's Y axis (straight down) approximates Earth. Set it to zero for a game in space, or to something smaller for the Moon.
- Engine
- Editor
- React
- Web Components
// Lunar gravity. The older setGravity() method is deprecated in favor of this property.
app.systems.rigidbody.gravity = new pc.Vec3(0, -1.62, 0);
Set Gravity in the PHYSICS section of the Scene Settings panel.
There is no gravity prop, so set it on the application from a component inside <Application>:
import { useEffect } from 'react';
import { useApp } from '@playcanvas/react/hooks';
function LunarGravity() {
const app = useApp();
useEffect(() => {
app.systems.rigidbody.gravity.set(0, -1.62, 0);
}, [app]);
return null;
}
<pc-scene gravity="0 -1.62 0">
<!-- ... -->
</pc-scene>
Units of Measurement
The physics engine interprets 1 unit as 1 meter and measures mass in kilograms. For objects to fall at a rate that looks right, size your scenes accordingly: a character who is 1.8 m tall should be 1.8 units high. Scenes built at a very different scale still simulate, but gravity will look too weak or too strong, and very small shapes are prone to tunneling through one another.
How the Simulation Runs
A few rules follow from the way the engine drives the simulation, and the rest of this section relies on them:
- The simulation steps at a fixed rate. Each frame, the physics world advances in fixed steps of 1/60 of a second, taking as many as the frame time requires (up to a limit). Bodies therefore behave the same at 30 and at 144 frames per second. On displays faster than 60 Hz some frames run no step at all, and body transforms are interpolated so that motion stays smooth.
- Physics owns dynamic bodies. After each step the engine writes the position and rotation of every dynamic body back to its entity. Anything you set on the entity's transform is overwritten, so dynamic bodies are moved with forces, velocities or
teleportinstead (see Rigid Bodies). - You own static and kinematic bodies. Their transforms are read from the entity at the start of each step, so you move them like any other entity.
- Events fire per step. Collision and trigger events are reported once per physics step, not per frame. A body resting on the floor produces a
contactevent every step for as long as it rests there.
See Also
- Rigid Bodies - Body types and properties, the next thing to read
- Collision Shapes - Giving bodies a shape
- Physics Settings - The PHYSICS section of the Editor's scene settings
- Collision and Triggers - Tutorial that builds a complete physics scene in the Editor