usePhysics
usePhysics provides an imperative API for controlling a Rapier rigid body. Use it inside children of a physics-enabled Actor to apply impulses, set velocities, teleport, and more.
tsx
import { usePhysics } from "@carverjs/core/hooks";Prerequisites #
Install
@react-three/rapier:bashpnpm add @react-three/rapierEnable physics on the
World:tsx<World physics={{ gravity: [0, -9.81, 0] }}>Add a
physicsprop to theActor:tsx<Actor type="primitive" shape="box" physics={{ bodyType: "dynamic" }}> <PlayerController /> </Actor>Call
usePhysics()inside<PlayerController />.
Quick Start #
tsx
import { usePhysics } from "@carverjs/core/hooks";
import { useInput, useGameLoop } from "@carverjs/core/hooks";
function PlayerController() {
const physics = usePhysics();
const { isAction } = useInput({
actions: { jump: ["Space"], left: ["KeyA"], right: ["KeyD"] },
});
useGameLoop(() => {
if (!physics) return;
if (isAction("left")) physics.setLinearVelocity([-5, 0, 0]);
if (isAction("right")) physics.setLinearVelocity([5, 0, 0]);
if (isAction("jump")) physics.applyImpulse([0, 10, 0]);
});
return null;
}Return Value #
Returns UsePhysicsReturn | null. Returns null when no physics context exists or the component is not inside a physics-enabled Actor.
| Method | Type | Description |
|---|---|---|
applyImpulse(impulse) | ([number, number, number]) => void | Apply an instantaneous force |
applyForce(force) | ([number, number, number]) => void | Apply a continuous force (resets each physics step) |
setLinearVelocity(vel) | ([number, number, number]) => void | Set linear velocity directly |
getLinearVelocity() | () => [number, number, number] | Get current linear velocity |
setAngularVelocity(vel) | ([number, number, number]) => void | Set angular velocity |
setTranslation(pos) | ([number, number, number]) => void | Teleport the body to a position |
getTranslation() | () => [number, number, number] | Get current position |
setRotation(quat) | ([number, number, number, number]) => void | Set rotation as quaternion [x, y, z, w] |
setEnabled(enabled) | (boolean) => void | Enable or disable the rigid body |
Full Example #
tsx
import { Game, World, Actor } from "@carverjs/core/components";
import { usePhysics, useInput, useGameLoop } from "@carverjs/core/hooks";
function PlayerController() {
const physics = usePhysics();
const { isActionJustPressed } = useInput({
actions: { jump: ["Space"] },
});
useGameLoop(() => {
if (!physics) return;
if (isActionJustPressed("jump")) {
physics.applyImpulse([0, 8, 0]);
}
});
return null;
}
function App() {
return (
<Game>
<World physics={{ gravity: [0, -9.81, 0] }}>
{/* Dynamic player */}
<Actor type="primitive" shape="box" color="blue" position={[0, 5, 0]}
physics={{ bodyType: "dynamic", mass: 1 }}
>
<PlayerController />
</Actor>
{/* Static ground */}
<Actor type="primitive" shape="plane" color="#eee" size={20}
rotation={[-Math.PI / 2, 0, 0]}
physics={{ bodyType: "fixed" }}
/>
</World>
</Game>
);
}Type Definitions #
See Types for UsePhysicsReturn, ActorPhysicsProps, RigidBodyType, PhysicsColliderType, and WorldPhysicsConfig.