Physics
PlayCanvas ships with a physics system. This enables realistic simulations of objects in 3D space, including gravity, collisions, forces and constraints. The physics system is powered by the Ammo.js physics engine.
Make sure you have sync-ammo
installed and usePhysics
enabled on your Application component to use physics.
You allow entities to participate in physics simulation by adding a RigidBody
and Collision
component to them. In the example below, we're creating a static ground, a falling sphere and a falling box.
- Demo
- Code
import { Entity } from '@playcanvas/react';
import { RigidBody, Collision, Render, Camera } from '@playcanvas/react/components';
import { useMaterial } from '@playcanvas/react/hooks';
import { useColorMode } from '@docusaurus/theme-common';
export const BasicPhysics = () => {
const { colorMode } = useColorMode();
const sphereMaterial = useMaterial({ diffuse: 'red' });
const boxMaterial = useMaterial({ diffuse: '#4ecdc4' });
const groundMaterial = useMaterial({ diffuse: '#95a5a6' });
const cameraColor = colorMode === 'dark' ? '#2a2a2a' : '#e4e0e0';
return (
<>
{/* Ground (static) */}
<Entity name="ground" position={[0, -2, 0]} scale={[10, 0.2, 10]}>
<RigidBody type="static" halfExtents={[5, 0.2, 5]} />
<Collision type="box" halfExtents={[5, 0.2, 5]} />
<Render type="box" material={groundMaterial} />
</Entity>
{/* Falling sphere */}
<Entity name="sphere" position={[-2, 8, 0]}>
<RigidBody type="dynamic" mass={1} />
<Collision type="sphere" />
<Render type="sphere" material={sphereMaterial} />
</Entity>
{/* Falling box */}
<Entity name="box" position={[2, 6, 0]}>
<RigidBody type="dynamic" mass={2} />
<Collision type="box" />
<Render type="box" material={boxMaterial} />
</Entity>
</>
);
};
Physics Properties
You can customize physics behavior by changing the various properties of the RigidBody
and Collision
components. Check out the Physics documentation for more information.
<RigidBody
type="dynamic"
mass={1} // Object mass
linearDamping={0.1} // Air resistance for movement
angularDamping={0.1} // Air resistance for rotation
friction={0.5} // Surface friction
restitution={0.3} // Bounciness (0 = no bounce, 1 = perfect bounce)
/>
<Collision
type="box"
halfExtents={[1, 1, 1]} // Size for box collision
radius={0.5} // Radius for sphere/cylinder collision
height={2} // Height for capsule/cylinder collision
/>
Using the usePhysics Hook
The physics engine is lazily loaded and instantiated. This prioritizes the first render of your application, allowing you to display something as soon as possible. This is great for performance, but you'll need to check the physics state to ensure it's loaded before you can use it.
The usePhysics
hook provides information about the physics engine state:
import { usePhysics } from '@playcanvas/react/hooks';
const PhysicsStatus = () => {
const { isPhysicsEnabled, isPhysicsLoaded, physicsError } = usePhysics();
if (physicsError) {
return <div>Physics error: {physicsError.message}</div>;
}
if (!isPhysicsLoaded) {
return <div>Loading physics...</div>;
}
return <div>Physics is ready!</div>;
};
For more detailed information about PlayCanvas physics, see the PlayCanvas Physics Documentation.