### Basic Usage Example
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Demonstrates the fundamental setup of a react-three-fiber scene with react-three-rapier physics. It includes the Physics component, a RigidBody with a Torus, and a CuboidCollider for the ground. Ensure Suspense is used for lazy initialization.
```tsx
import { Box, Torus } from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import { Physics, RigidBody, CuboidCollider } from "@react-three/rapier";
const App = () => {
return (
);
};
```
--------------------------------
### InstancedRigidBodies: New Setup
Source: https://github.com/pmndrs/react-three-rapier/wiki/0.12.x-to-0.13.x-Migration-guide
Demonstrates the new setup for InstancedRigidBodies using an 'instances' prop for individual instance properties and 'colliderNodes' for shapes. Each instance requires a 'key'.
```tsx
const instances = Array.from({length: COUNT}).map((_, index) => ({
key: 'instance_' + index,
position: [1,2,3],
rotation: [1,2,3],
scale: [1,1,1],
restitution: Math.random(),
}))
,
]}>
...
```
--------------------------------
### InstancedRigidBodies: Previous Setup
Source: https://github.com/pmndrs/react-three-rapier/wiki/0.12.x-to-0.13.x-Migration-guide
Shows the previous method of setting up InstancedRigidBodies using separate arrays for positions, rotations, and scales.
```tsx
const positions = Array.from({length: COUNT}).map(() => [1, 2, 3])
const rotations = Array.from({length: COUNT}).map(() => [3,2,1])
const scales = Array.from({length: COUNT}).map(() => [1,1,1])
...
```
--------------------------------
### Physics Component Setup
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Illustrates the root Physics component for a react-three-rapier world. It requires wrapping in Suspense and allows configuration of gravity, interpolation, and colliders. Refer to PhysicsProps for all available options.
```tsx
const Scene = () => {
return (
);
};
```
--------------------------------
### Fixed Joint Example
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Demonstrates how to create a fixed joint between two rigid bodies. Requires local space positions and orientations for both bodies.
```tsx
const JointedThing = () => {
const bodyA = useRef(null);
const bodyB = useRef(null);
const joint = useFixedJoint(bodyA, bodyB, [
// Position of the joint in bodyA's local space
[0, 0, 0],
// Orientation of the joint in bodyA's local space
[0, 0, 0, 1],
// Position of the joint in bodyB's local space
[0, 0, 0],
// Orientation of the joint in bodyB's local space
[0, 0, 0, 1]
]);
return (
);
};
```
--------------------------------
### Revolute Joint Example
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Shows how to implement a revolute joint, allowing rotation along one axis while restricting other movements. Requires local space positions and the joint axis.
```tsx
const JointedThing = () => {
const bodyA = useRef(null);
const bodyB = useRef(null);
const joint = useRevoluteJoint(bodyA, bodyB, [
// Position of the joint in bodyA's local space
[0, 0, 0],
// Position of the joint in bodyB's local space
[0, 0, 0],
// Axis of the joint, expressed in the local-space of
// the rigid-bodies it is attached to. Cannot be [0,0,0].
[0, 1, 0]
]);
return (
);
};
```
--------------------------------
### Prismatic Joint Example
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Provides an example of a prismatic joint, enabling translation along one axis while preventing other relative motions. Requires local space positions and the joint axis.
```tsx
const JointedThing = () => {
const bodyA = useRef(null);
const bodyB = useRef(null);
const joint = usePrismaticJoint(bodyA, bodyB, [
// Position of the joint in bodyA's local space
[0, 0, 0],
// Position of the joint in bodyB's local space
[0, 0, 0],
// Axis of the joint, expressed in the local-space of
// the rigid-bodies it is attached to. Cannot be [0,0,0].
[0, 1, 0]
]);
return (
);
};
```
--------------------------------
### RigidBodyApi Changes: Get and Set Translation
Source: https://github.com/pmndrs/react-three-rapier/wiki/0.12.x-to-0.13.x-Migration-guide
Demonstrates how to access translation and raw instances, and set translation for RigidBodies. Previously used RigidBodyApi, now uses direct RapierRigidBody reference and vec3 helper for conversions.
```tsx
import { RigidBodyApi } from '@react-three/rapier'
...
const ref = useRef()
useEffect(() => {
if (ref.current) {
// get translation
const position = ref.current.translation() // Three.Vector3
// get raw instance
const instance = ref.current.raw(); // Rapier.RigidBody
// set translation
ref.current.setTranslation({x: 0, y: 10, z: 0})
}
}, [])
```
```tsx
import { vec3, RapierRigidBody } from '@react-three/rapier'
...
const ref = useRef()
useEffect(() => {
if (ref.current) {
// get translation
const translation = ref.current.translation() // Rapier.Vector
const position = vec3(translation) // Three.Vector3
// get raw instance
const instance = ref.current; // Rapier.RigidBody
// set translation
ref.current.setTranslation({x: 0, y: 10, z: 0}, true)
}
}, [])
```
--------------------------------
### Spherical Joint Example
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Illustrates the creation of a spherical joint between two rigid bodies, preventing relative translational motion. Requires local space positions for both bodies.
```tsx
const JointedThing = () => {
const bodyA = useRef(null);
const bodyB = useRef(null);
const joint = useSphericalJoint(bodyA, bodyB, [
// Position of the joint in bodyA's local space
[0, 0, 0],
// Position of the joint in bodyB's local space
[0, 0, 0]
]);
return (
);
};
```
--------------------------------
### Configure Revolute Joint Motor Velocity
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Example of configuring the motor velocity for a revolute joint. Requires the joint ref and motor parameters.
```tsx
const WheelJoint = ({ bodyA, bodyB }) => {
const joint = useRevoluteJoint(bodyA, bodyB, [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
]);
useFrame(() => {
if (joint.current) {
joint.current.configureMotorVelocity(10, 2);
}
}, []);
return null;
};
```
--------------------------------
### Generate ConvexHull Colliders for All Meshes in a RigidBody
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Use the 'colliders' prop on the component to set the default collider type for all RigidBodies within the scene. This example sets the default to 'hull'.
```tsx
const Scene = () => (
);
```
--------------------------------
### Create Compound Shapes with Custom BallColliders
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Manually create and attach Collider components to a RigidBody to form compound shapes. This example demonstrates a compound shape made of two custom BallColliders.
```tsx
const Scene = () => (<>
{/* Make a compound shape with two custom BallColliders */}
{/* Make a compound shape with two custom BallColliders, an automatic BallCollider,
Two automatic MeshColliders, based on two different shape types */}
<>)
```
--------------------------------
### World Snapshotting and Restoration
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Demonstrates how to serialize the physics world into a `Uint8Array` snapshot using `world.takeSnapshot()` and restore it using `rapier.World.restoreSnapshot()`. This is useful for saving and loading game states, but requires the world structure to remain identical.
```tsx
import { useRapier } from '@react-three/rapier';
const SnapshottingComponent = () => {
const { world, setWorld, rapier } = useRapier();
const worldSnapshot = useRef();
// Store the snapshot
const takeSnapshot = () => {
const snapshot = world.takeSnapshot()
worldSnapshot.current = snapshot
}
// Create a new World from the snapshot, and replace the current one
const restoreSnapshot = () => {
setWorld(rapier.World.restoreSnapshot(worldSnapshot.current))
}
return <>
...
...
...
...
...
>
}
```
--------------------------------
### Using the Attractor Component
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier-addons/README.md
Demonstrates how to use the Attractor component with different configurations for strength, range, type, and collision groups.
```tsx
import { Attractor } from "@react-three/rapier-addons"
// Standard attractor
// An attractor with negative strength, repels RigidBodies
// You can also assign InteractionGroups.
// An attractor belonging to group 0 only affecting bodies in group 2, and 3
```
--------------------------------
### Migrating from WorldApi to Proxied World Instance
Source: https://github.com/pmndrs/react-three-rapier/wiki/0.15.x-to-1.x.x-Migration-guide
Before: Accessing the WorldApi. Now: Accessing the proxied singleton world instance directly.
```tsx
import { useRapier } from "@react-three/rapier";
const Component = () => {
const { world } = useRapier();
useEffect(() => {
// Access to the WorldApi (limited)
world.raw().bodies.forEach(() => {
// Do something
});
// Access the raw Rapier World instance
const rawWorldInstance = world.raw();
rawWorldInstance.raw().setGravity(new Vector3(0, -9.81, 0));
}, []);
};
```
```tsx
import { useRapier } from "@react-three/rapier";
const Component = () => {
const { world } = useRapier();
useEffect(() => {
// Access the Rapier World instance directly
world.bodies.forEach(() => {
// Do something
});
world.setGravity(new Vector3(0, -9.81, 0));
}, []);
};
```
--------------------------------
### Using Attractor Component with Addons Package (Current)
Source: https://github.com/pmndrs/react-three-rapier/wiki/0.14.x-to-0.15.x-Migration-guide
Illustrates the current method of using the `Attractor` component, which is now imported from the separate `@react-three/rapier-addons` package.
```tsx
import { Physics } from '@react-three/rapier'
import { Attractor } from '@react-three/rapier-addons'
```
--------------------------------
### Using Attractor Component in React Three Rapier (Previous)
Source: https://github.com/pmndrs/react-three-rapier/wiki/0.14.x-to-0.15.x-Migration-guide
Demonstrates the previous approach of importing and using the `Attractor` component directly from the main `@react-three/rapier` package.
```tsx
import { Physics, Attractor } from '@react-three/rapier'
```
--------------------------------
### Configure Fixed Physics Time Step
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Set the `timeStep` prop on the `` component to control the simulation's frame rate. A value of `1 / 30` will simulate at 30 FPS.
```tsx
{/* ... */}
```
--------------------------------
### Spring Joint Implementation
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Shows how to use the useSpringJoint hook to apply a force proportional to the distance between two bodies. Requires calculating stiffness and damping based on mass and desired properties.
```tsx
const JointedThing = () => {
const bodyA = useRef(null);
const bodyB = useRef(null);
const mass = 1;
const springRestLength = 0;
const stiffness = 1.0e3;
const criticalDamping = 2.0 * Math.sqrt(stiffness * mass);
const dampingRatio = props.jointNum / (props.total / 2);
const damping = dampingRatio * criticalDamping;
const joint = useSpringJoint(bodyA, bodyB, [
// Position of the joint in bodyA's local space
[0, 0, 0],
// Position of the joint in bodyB's local space
[0, 0, 0],
// Spring rest length
springRestLength,
// Spring stiffness
stiffness,
// Spring damping
damping
]);
return (
);
};
```
--------------------------------
### Converting Rapier Vectors and Quaternions
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Use helper functions like `vec3`, `quat`, and `euler` for type conversions between Rapier and Three.js. Setting values can be done directly with Three.js types.
```tsx
import { RapierRigidBody, quat, vec3, euler } from "@react-three/rapier";
const Scene = () => {
const rigidBody = useRef(null);
useEffect(() => {
if (rigidBody.current) {
const position = vec3(rigidBody.current.translation());
const quaternion = quat(rigidBody.current.rotation());
const eulerRot = euler().setFromQuaternion(
quat(rigidBody.current.rotation())
);
// While Rapier's return types need conversion, setting values can be done directly with Three.js types
rigidBody.current.setTranslation(position, true);
rigidBody.current.setRotation(quaternion, true);
rigidBody.current.setAngvel({ x: 0, y: 2, z: 0 }, true);
}
}, []);
return (
);
};
```
--------------------------------
### Physics Component Prop Changes
Source: https://github.com/pmndrs/react-three-rapier/wiki/1.2.1-to-1.3.0-Migration-guide
This snippet shows the changes in props for the `` component to match new world initiation properties in Rapier 0.12.0. Direct alternatives for all old parameters may not exist.
```diff
- maxStabilizationIterations?: number
- maxVelocityFrictionIterations?: number
- maxVelocityIterations?: number
+ allowedLinearError?: number
+ numSolverIterations?: number
+ numAdditionalFrictionIterations?: number
+ numInternalPgsIterations?: number
+ minIslandSize?: number
+ maxCcdSubsteps?: number
```
--------------------------------
### Using Debug Component in React Three Rapier (Previous)
Source: https://github.com/pmndrs/react-three-rapier/wiki/0.14.x-to-0.15.x-Migration-guide
Illustrates the previous method of enabling debug mode using the `` component within the `` component.
```tsx
import { Physics, Debug } from '@react-three/rapier'
...
```
--------------------------------
### Rope Joint Implementation
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Demonstrates how to use the useRopeJoint hook to limit the maximum distance between two rigid bodies. Requires two refs for the bodies and an array of joint parameters.
```tsx
const JointedThing = () => {
const bodyA = useRef(null);
const bodyB = useRef(null);
const joint = useRopeJoint(bodyA, bodyB, [
// Position of the joint in bodyA's local space
[0, 0, 0],
// Position of the joint in bodyB's local space
[0, 0, 0],
// The max distance between the two bodies / length of the rope
1
]);
return (
);
};
```
--------------------------------
### Configure Variable Physics Time Step
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Set the `timeStep` prop to the string 'vary' to allow the simulation's time step to adjust to each frame's delta time. This can cause instability and non-deterministic behavior.
```tsx
{/* ... */}
```
--------------------------------
### Manual Physics Stepping
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Manually steps the physics simulation by calling the `step` method from the `useRapier` hook. Useful for controlling the simulation's update rate independently.
```tsx
const { step } = useRapier();
step(1 / 60);
```
--------------------------------
### Enabling Debug Mode in React Three Rapier (Current)
Source: https://github.com/pmndrs/react-three-rapier/wiki/0.14.x-to-0.15.x-Migration-guide
Shows the current method for enabling debug mode by passing the `debug` prop directly to the `` component.
```tsx
import { Physics } from '@react-three/rapier'
...
```
--------------------------------
### Physics Debugging with React Three Rapier
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Enable live visualization of all colliders in a scene by setting the 'debug' prop to true on the component. This is useful for verifying collision shapes and interactions.
```tsx
import { Box, Sphere } from "@react-three/drei";
import { RigidBody } from "@react-three/rapier";
const Scene = () => {
return (
);
};
```
--------------------------------
### Applying Forces and Torques to RigidBody
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Access a RigidBody's ref to apply impulses, continuous forces, and torques. Ensure the ref is available before calling methods.
```tsx
import { RigidBody, RapierRigidBody } from "@react-three/rapier";
const Scene = () => {
const rigidBody = useRef(null);
useEffect(() => {
if (rigidBody.current) {
// A one-off "push"
rigidBody.current.applyImpulse({ x: 0, y: 10, z: 0 }, true);
// A continuous force
rigidBody.current.addForce({ x: 0, y: 10, z: 0 }, true);
// A one-off torque rotation
rigidBody.current.applyTorqueImpulse({ x: 0, y: 10, z: 0 }, true);
// A continuous torque
rigidBody.current.addTorque({ x: 0, y: 10, z: 0 }, true);
}
}, []);
return (
);
};
```
--------------------------------
### Workaround for Contact Force Events
Source: https://github.com/pmndrs/react-three-rapier/wiki/1.2.1-to-1.3.0-Migration-guide
If you are using contact force events and observe new behavior or differing magnitudes after updating, set `numSolverIterations` to `1` as a workaround.
```tsx
...
```
--------------------------------
### Instanced Rigid Bodies with Single Collider
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Wrap a single Three.InstancedMesh in InstancedRigidBodies to generate individual rigid bodies for each instance. Colliders can be defined globally for all instances. Access and manipulate individual instances via the ref.
```tsx
import { InstancedRigidBodies, RapierRigidBody } from "@react-three/rapier";
const COUNT = 1000;
const Scene = () => {
const rigidBodies = useRef(null);
useEffect(() => {
if (!rigidBodies.current) {
return;
}
// You can access individual instanced by their index
rigidBodies.current[40].applyImpulse({ x: 0, y: 10, z: 0 }, true);
rigidBodies.current.at(100).applyImpulse({ x: 0, y: 10, z: 0 }, true);
// Or update all instances
rigidBodies.current.forEach((api) => {
api.applyImpulse({ x: 0, y: 10, z: 0 }, true);
});
}, []);
// We can set the initial positions, and rotations, and scales, of
// the instances by providing an array of InstancedRigidBodyProps
// which is the same as RigidBodyProps, but with an additional "key" prop.
const instances = useMemo(() => {
const instances: InstancedRigidBodyProps[] = [];
for (let i = 0; i < COUNT; i++) {
instances.push({
key: "instance_" + Math.random(),
position: [Math.random() * 10, Math.random() * 10, Math.random() * 10],
rotation: [Math.random(), Math.random(), Math.random()]
});
}
return instances;
}, []);
return (
);
};
```
--------------------------------
### Configure Collider Interaction Groups
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Use `interactionGroups` to generate bitmasks for collider group memberships and interactions. The first argument specifies the collider's group(s), and the second specifies the groups it should interact with.
```tsx
```
```tsx
```
```tsx
```
--------------------------------
### On-Demand Rendering with Independent Physics Loop
Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md
Configures the physics simulation to run in its own `requestAnimationFrame` loop, updating the canvas only when active bodies change. This is achieved by setting `updateLoop="independent"` on the `` component and using `frameloop="demand"` on the `