Agent skill
r3f-physics
React Three Fiber physics with Rapier - RigidBody, colliders, forces, joints. Use when adding physics simulation, collision detection, or character controllers.
Stars
163
Forks
31
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/r3f-physics
SKILL.md
React Three Fiber Physics (Rapier)
Setup
bash
npm install @react-three/rapier
tsx
import { Physics, RigidBody } from '@react-three/rapier'
function Scene() {
return (
<Physics gravity={[0, -9.81, 0]} debug>
<RigidBody>
<mesh>
<boxGeometry />
<meshStandardMaterial />
</mesh>
</RigidBody>
<RigidBody type="fixed">
<mesh position={[0, -2, 0]}>
<boxGeometry args={[10, 0.5, 10]} />
<meshStandardMaterial />
</mesh>
</RigidBody>
</Physics>
)
}
RigidBody Types
tsx
// Dynamic - affected by gravity and forces
<RigidBody type="dynamic">...</RigidBody>
// Fixed - immovable
<RigidBody type="fixed">...</RigidBody>
// KinematicPosition - moved via position, affects others
<RigidBody type="kinematicPosition">...</RigidBody>
// KinematicVelocity - moved via velocity
<RigidBody type="kinematicVelocity">...</RigidBody>
RigidBody Properties
tsx
<RigidBody
mass={1}
friction={0.7}
restitution={0.3} // Bounciness
linearDamping={0.5}
angularDamping={0.5}
gravityScale={1}
lockTranslations // Lock all translations
lockRotations // Lock all rotations
enabledTranslations={[true, true, false]} // Lock Z translation
ccd // Continuous collision detection
>
Colliders
tsx
// Auto-generated from mesh
<RigidBody colliders="cuboid"> // or "ball", "hull", "trimesh"
<mesh>...</mesh>
</RigidBody>
// Manual colliders
import { CuboidCollider, BallCollider, CapsuleCollider } from '@react-three/rapier'
<RigidBody colliders={false}>
<CuboidCollider args={[0.5, 0.5, 0.5]} />
<BallCollider args={[0.5]} position={[0, 1, 0]} />
<CapsuleCollider args={[0.5, 1]} />
</RigidBody>
Forces & Impulses
tsx
function PhysicsBox() {
const ref = useRef()
const jump = () => {
ref.current.applyImpulse({ x: 0, y: 5, z: 0 }, true)
}
const push = () => {
ref.current.applyForce({ x: 10, y: 0, z: 0 }, true)
}
return (
<RigidBody ref={ref}>
<mesh onClick={jump}>
<boxGeometry />
<meshStandardMaterial />
</mesh>
</RigidBody>
)
}
Collision Events
tsx
<RigidBody
onCollisionEnter={({ manifold, other }) => {
console.log('Collision with', other.rigidBodyObject.name)
console.log('Contact force', manifold.solverContactForce)
}}
onCollisionExit={({ other }) => {
console.log('Stopped colliding with', other.rigidBodyObject.name)
}}
>
Sensors (Triggers)
tsx
<RigidBody>
<CuboidCollider
args={[2, 2, 2]}
sensor
onIntersectionEnter={({ other }) => {
console.log('Entered trigger zone')
}}
onIntersectionExit={({ other }) => {
console.log('Left trigger zone')
}}
/>
</RigidBody>
Collision Groups
tsx
import { interactionGroups } from '@react-three/rapier'
// Group 0 collides with groups 0 and 1
<RigidBody collisionGroups={interactionGroups(0, [0, 1])}>
// Group 1 only collides with group 0
<RigidBody collisionGroups={interactionGroups(1, [0])}>
Joints
tsx
import { useSphericalJoint, useRevoluteJoint } from '@react-three/rapier'
function Pendulum() {
const anchor = useRef()
const ball = useRef()
useSphericalJoint(anchor, ball, [
[0, 0, 0], // Anchor point on first body
[0, 2, 0], // Anchor point on second body
])
return (
<>
<RigidBody ref={anchor} type="fixed">...</RigidBody>
<RigidBody ref={ball}>...</RigidBody>
</>
)
}
Character Controller
tsx
import { CapsuleCollider, RigidBody, useRapier } from '@react-three/rapier'
function Player() {
const ref = useRef()
const { rapier, world } = useRapier()
useFrame(() => {
// Move with velocity
ref.current.setLinvel({ x: moveX * 5, y: ref.current.linvel().y, z: moveZ * 5 })
})
return (
<RigidBody ref={ref} lockRotations>
<CapsuleCollider args={[0.5, 0.5]} />
</RigidBody>
)
}
Performance Tips
- Use simple collider shapes
- Avoid trimesh for dynamic bodies
- Enable sleeping for inactive bodies
- Use collision groups to limit checks
- Keep fixed timestep for stability
Didn't find tool you were looking for?