PhysicsSyncSystem
Initializes and manages the Rapier physics world, creates rigid bodies and colliders from PhysicsComponent authoring state, steps the simulation each frame, and writes the results back to entity transforms.
Overview
PhysicsSyncSystem runs every frame and is responsible for:
- Lazy-initializing the Rapier physics engine (loaded asynchronously via
@dimforge/rapier3d-compat) the first time the system updates. - Creating a Rapier
RigidBodyandColliderfor each entity that has aPhysicsComponentandObject3DRef. - Recreating bodies and colliders when their type, shape, or size changes (detected by per-entity signatures).
- Stepping the Rapier world each frame with the clamped delta time.
- Writing the simulation's output (body translation + rotation) back into the entity's
TransformComponentand THREE.jsObject3Dfor dynamic and kinematic bodies. - Applying per-axis translation/rotation locks from
PhysicsComponent.values.rigidbody. - Handling
isSensorcolliders that fire collision events without generating a physical response.
Queried components
| Component | Access |
|---|---|
PhysicsComponent | Read + mutate (rigidBody, collider live refs; values for authoring state) |
Object3DRef | Read (initial world position for body placement) |
TransformComponent | Mutate (position, rotation written from simulation output) |
Environment | Read (global gravity vector) |
Supported rigid body types
| Type | Description |
|---|---|
dynamic | Fully simulated; affected by gravity and forces. |
fixed | Immovable; acts as a static collider. |
kinematicPosition | Moved by setting position directly; not affected by physics. |
kinematicVelocity | Moved by setting velocity; interacts with dynamics. |
Supported collider shapes
| Shape | Parameters |
|---|---|
cuboid | width, height, depth |
ball | radius |
capsule | radius, height |
cylinder | radius, height |
trimesh | Auto-extracted from the entity's THREE.js geometry |
Behavior notes
- Async init — the Rapier WASM module is loaded once on the first
update()call. Physics simulation does not start until the module is ready; entities created before init are processed on the first frame after init completes. - Trimesh —
trimeshcolliders extract vertex/index data from the entity'sTHREE.BufferGeometry. The extracted data is cached per entity by a geometry signature. - Sensor colliders — setting
values.collider.isSensor = truecreates a Rapier sensor collider. Sensor contacts do not generate forces but can be used for overlap/trigger queries. - Gravity — the global gravity vector is read from the
Environmentcomponent (gravityfield, default{ x: 0, y: -9.81, z: 0 }) and applied to the Rapier world gravity setting each frame. - Preview only — the system is typically constructed with
{ isEditor: false }for preview. In the editor the physics world step is skipped so objects don't fall during authoring.
API reference
- Class:
PhysicsComponent - Source:
core/systems/PhysicsSyncSystem.ts

