Rigid Bodies
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.
Body Types#
Dynamic (Type 0)
Fully simulated bodies affected by gravity, forces, and collisions. Used for movable objects like crates, balls, and debris.
Fixed (Type 1)
Immovable bodies that never move. Optimized for static geometry like walls, floors, and terrain.
Kinematic Position (Type 2)
Bodies moved by setting position/rotation directly. They affect dynamic bodies but aren't affected by them. Used for moving platforms.
Kinematic Velocity (Type 3)
Bodies moved by setting velocity. Provides smoother motion than position-based kinematics for animated objects.
Component Properties#
| 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#
Dynamic bodies are fully simulated and respond to all physics forces. They are the most common body type for interactive objects.
- Affected by gravity
- Respond to forces and impulses
- Collide with all body types
- Can have mass, inertia, friction, restitution
- Support sleeping/waking for performance
- Examples: boxes, balls, characters, vehicles, debris
// 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 force api.applyImpulse({ x: move.x * moveForce, y: 0, z: move.y * moveForce, }); // Jump if (jumpDown) { api.applyImpulse({ x: 0, y: jumpForce, z: 0 }); } };};Mass and Inertia#
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 and Restitution#
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, // Dynamic mass: 5.0, friction: 0.05, restitution: 0.1,} // Bouncy ball{ type: 0, // Dynamic mass: 0.5, friction: 0.5, restitution: 0.9,}Continuous Collision Detection (CCD)#
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.
- Enable for bullets, projectiles, fast vehicles
- Prevents tunneling through thin walls
- More expensive than discrete collision
- Not needed for slow-moving objects
// Bullet with CCD enabledexport default (api) => { const bulletSpeed = 50.0; return (dt) => { // Move bullet forward at high speed api.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).
Sleeping and Waking#
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 sleep after being stationary for ~0.5 seconds
- Sleeping bodies skip simulation (zero cost)
- Woken by collisions, forces, or nearby active bodies
- Improves performance in scenes with many static or resting objects
// 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 itLocking Translation and Rotation Axes#
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}Linear and Angular Damping#
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#
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.
Kinematic Position-Based (Type 2)#
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 position const offset = Math.sin(time * speed) * distance; api.position = { x: api.position.x, y: offset, z: api.position.z, }; };};Kinematic Velocity-Based (Type 3)#
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 velocity api.velocity = { x: isOpen ? openSpeed : -openSpeed, y: 0, z: 0, }; };};Static Bodies (Fixed)#
Static bodies never move and are optimized for zero-cost simulation. Use for level geometry, walls, floors, and terrain.
- Never move (position/rotation cannot change)
- Most efficient body type
- Other bodies collide with them normally
- Examples: walls, floors, terrain, buildings
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.
Common Patterns#
High-Speed Projectile#
{ type: 0, // Dynamic mass: 0.1, friction: 0.1, restitution: 0.2, ccd: true, // Important for fast objects!}Character Body#
{ type: 0, // Dynamic mass: 70.0, // ~70kg adult human friction: 0.0, // No friction (controlled by script) restitution: 0.0, // No bounce lockRotation: [1, 0, 1], // Only rotate around Y}Vehicle Chassis#
{ type: 0, // Dynamic mass: 1000.0, // 1 ton friction: 0.5, restitution: 0.1, // Use Vehicle component for wheels}