First Person Controls
Learn how to configure the SimpleCharacter for first person perspective.
In this tutorial we will configure the SimpleCharacter
to use first person controls with the following result:
Here's a preview of this tutorial's result:
import { Sky } from '@react-three/drei' import { Canvas } from '@react-three/fiber' import { Viverse, SimpleCharacter, FixedBvhPhysicsBody, PrototypeBox, FirstPersonCharacterCameraBehavior, PointerLockInput, LocomotionKeyboardInput, } from '@react-three/viverse' export default function App() { return ( <Canvas onClick={(e) => (e.target as HTMLElement).requestPointerLock()} style={{ position: 'absolute', inset: '0', touchAction: 'none' }} > <Viverse> <Sky /> <directionalLight intensity={1.2} position={[-10, 10, -10]} /> <ambientLight intensity={1} /> <SimpleCharacter model={false} input={[LocomotionKeyboardInput, PointerLockInput]} cameraBehavior={FirstPersonCharacterCameraBehavior} /> <FixedBvhPhysicsBody> <PrototypeBox scale={[10, 1, 15]} position={[0, -0.5, 0]} /> </FixedBvhPhysicsBody> </Viverse> </Canvas> ) }
First, we switch from third-person to first-person camera behavior and hide the character model to prevent the model from occluding the players view.
<SimpleCharacter
model={false}
cameraBehavior={FirstPersonCharacterCameraBehavior}
// ... other props
/>
Changes:
model={false}
- Hides the character model since in first-person view, you don't want to see your own charactercameraBehavior={FirstPersonCharacterCameraBehavior}
- Switches from the default third-person camera to first-person camera behavior
Next, you need to set up the appropriate input controls for first-person movement and looking around:
<SimpleCharacter
input={[LocomotionKeyboardInput, PointerLockInput]}
// ... other props
/>
Input components:
LocomotionKeyboardInput
- Handles WASD movement controls for walking aroundPointerLockInput
- Enables mouse look controls for rotating the camera/view direction
Finally, we need to enable pointer locking when the user clicks on the canvas for the PointerLockInput
to work properly:
<Canvas
onClick={(e) => (e.target as HTMLElement).requestPointerLock()}
>
{/* ... rest of your scene */}
</Canvas>
What this does:
onClick={(e) => (e.target as HTMLElement).requestPointerLock()}
- When the user clicks anywhere on the canvas, it requests pointer lock, which captures the mouse cursor and allows for unlimited mouse movement for camera control