Web Engine Docs
Preparing documentation
Use the search bar to quickly find any topic
Preparing documentation
Use the search bar to quickly find any topic
Comprehensive guide to rigid body dynamics in Web Engine. Learn about body types, mass properties, damping, sleeping, and continuous collision detection.
The RigidBody component makes an entity participate in physics simulation. It defines how an object moves and responds to forces, collisions, and constraints. Web Engine supports four body types: Dynamic, Fixed, Kinematic Position-Based, and Kinematic Velocity-Based.
Fully simulated bodies affected by gravity, forces, and collisions. Used for movable objects like crates, balls, and debris.
Immovable bodies that never move. Optimized for static geometry like walls, floors, and terrain.
Bodies moved by setting position/rotation directly. They affect dynamic bodies but aren't affected by them. Used for moving platforms.
Bodies moved by setting velocity. Provides smoother motion than position-based kinematics for animated objects.
| Property | Type | Default | Description |
|---|---|---|---|
| type | enum | 0 (Dynamic) | Body type: 0=Dynamic, 1=Fixed, 2=Kinematic(Pos), 3=Kinematic(Vel) |
| mass | float | 1.0 | Mass in kilograms (Dynamic bodies only) |
| friction | float | 0.5 | Surface friction coefficient (0-1) |
| restitution | float | 0.0 | Bounciness coefficient (0=no bounce, 1=perfect bounce) |
| velocity | vec3 | [0,0,0] | Linear velocity in m/s |
| angularVelocity | vec3 | [0,0,0] | Angular velocity in rad/s |
| ccd | boolean | false | Enable Continuous Collision Detection |
| lockRotation | vec3 | [0,0,0] | Lock rotation axes (1=locked, 0=free) |
Dynamic bodies are fully simulated and respond to all physics forces. They are the most common body type for interactive objects.
// Create a dynamic rigid body in the editor// 1. Select an entity with a Transform// 2. Add RigidBody component// 3. Set type to 0 (Dynamic)// 4. Configure mass, friction, restitution// 5. Add a Collider component// 6. Press Play// Script example: Apply forces to a dynamic bodyexport default (api) => {const moveForce = 10.0;const jumpForce = 15.0;return (dt) => {const { move, jumpDown } = api.input;// Apply movement forceapi.applyImpulse({x: move.x * moveForce,y: 0,z: move.y * moveForce,});// Jumpif (jumpDown) {api.applyImpulse({ x: 0, y: jumpForce, z: 0 });}};};
Mass determines how much force is required to move a body. Inertia is automatically calculated based on mass and collider shape. Heavier objects require more force to move and are harder to rotate.
| Mass | Use Case | Examples |
|---|---|---|
| 0.1 - 1.0 | Light objects | Paper, balloons, feathers |
| 1.0 - 10.0 | Medium objects | Boxes, props, characters |
| 10.0 - 100.0 | Heavy objects | Barrels, furniture, vehicles |
| 100.0+ | Very heavy objects | Boulders, tanks, buildings |
Mass Best Practices
Keep mass ratios reasonable (avoid 0.1kg object colliding with 1000kg object). Extreme mass differences can cause instability. Use collision groups to prevent unrealistic interactions.
Friction resists sliding motion between surfaces. Restitution (bounciness) determines how much energy is preserved in collisions.
| Material | Friction | Restitution | Description |
|---|---|---|---|
| Ice | 0.05 | 0.1 | Very slippery, minimal bounce |
| Wood | 0.4 | 0.3 | Medium friction, low bounce |
| Rubber | 0.8 | 0.7 | High friction, high bounce |
| Metal | 0.3 | 0.4 | Low friction, medium bounce |
| Rubber Ball | 0.5 | 0.9 | Perfect bounce |
// Ice physics (slippery){type: 0, // Dynamicmass: 5.0,friction: 0.05,restitution: 0.1,}// Bouncy ball{type: 0, // Dynamicmass: 0.5,friction: 0.5,restitution: 0.9,}
CCD prevents fast-moving objects from tunneling through thin obstacles. It's more expensive than discrete collision detection, so only enable it for bullets, projectiles, and other high-speed objects.
// Bullet with CCD enabledexport default (api) => {const bulletSpeed = 50.0;return (dt) => {// Move bullet forward at high speedapi.velocity = {x: 0,y: 0,z: bulletSpeed,};// CCD prevents tunneling through thin walls// Enable CCD in inspector: RigidBody > ccd = true};};
Performance Impact
CCD has a significant performance cost. Only enable it for objects that actually need it (typically moving faster than 20 m/s through thin geometry).
Bodies that haven't moved for a while automatically enter sleep mode to save CPU. Sleeping bodies skip simulation until something wakes them (collision, force applied, nearby movement).
// Bodies automatically sleep when stationary// No configuration needed - it's automatic!// Wake a sleeping body with an impulseapi.applyImpulse({ x: 0, y: 5, z: 0 });// Or by moving nearby bodies that collide with it
Lock specific axes to constrain motion. Useful for 2D physics, top-down games, or restricting rotation.
// 2D physics (lock Z-axis){lockRotation: [1, 1, 0], // Lock X and Y rotation (only Z rotates)}// Top-down game character (no tipping over){lockRotation: [1, 0, 1], // Lock X and Z rotation (only Y rotates)}// Elevator (only vertical movement){lockRotation: [1, 1, 1], // Lock all rotation}
Damping gradually reduces velocity over time, simulating air resistance or drag. Higher damping values make objects slow down faster.
| Damping | Effect | Use Case |
|---|---|---|
| 0.0 | No damping | Space, frictionless motion |
| 0.1 - 0.5 | Light damping | Normal objects in air |
| 0.5 - 2.0 | Medium damping | Objects in water |
| 2.0 - 10.0 | Heavy damping | Thick fluids, viscous materials |
Damping vs Friction
Friction resists sliding between surfaces (only when touching). Damping resists motion through space (always active, like air resistance).
Kinematic bodies are moved by code, not physics. They push dynamic bodies but aren't affected by them. Perfect for moving platforms, elevators, and doors.
Set position and rotation directly each frame. Good for simple back-and-forth motion.
// Moving platform - kinematic position-basedexport default (api) => {const speed = 2.0;const distance = 5.0;let time = 0;return (dt) => {time += dt;// Oscillate positionconst offset = Math.sin(time * speed) * distance;api.position = {x: api.position.x,y: offset,z: api.position.z,};};};
Set velocity to move smoothly. Rapier handles the integration. Better for animated or scripted motion.
// Animated door - kinematic velocity-basedexport default (api) => {let isOpen = false;const openSpeed = 1.5;return (dt) => {if (api.input.interact) {isOpen = !isOpen;}// Move door with velocityapi.velocity = {x: isOpen ? openSpeed : -openSpeed,y: 0,z: 0,};};};
Static bodies never move and are optimized for zero-cost simulation. Use for level geometry, walls, floors, and terrain.
When to Use Static
If an object will never move, always use a static body. They have near-zero performance cost compared to dynamic or kinematic bodies.
{type: 0, // Dynamicmass: 0.1,friction: 0.1,restitution: 0.2,ccd: true, // Important for fast objects!}
{type: 0, // Dynamicmass: 70.0, // ~70kg adult humanfriction: 0.0, // No friction (controlled by script)restitution: 0.0, // No bouncelockRotation: [1, 0, 1], // Only rotate around Y}
{type: 0, // Dynamicmass: 1000.0, // 1 tonfriction: 0.5,restitution: 0.1,// Use Vehicle component for wheels}