import { Capsule, PerspectiveCamera, PointerLockControls } from "@react-three/drei"; import { useFrame } from "@react-three/fiber"; import { useContext, useEffect, useRef } from "react"; import { AppContext } from "../App"; import { CapsuleCollider, RapierCollider, RapierRigidBody, RigidBody, useRapier, vec3 } from "@react-three/rapier"; import { quat } from "@react-three/rapier"; import { Euler, Object3D, Vector3 } from "three"; import { useBeforePhysicsStep } from "@react-three/rapier"; const _movespeed = 3.0; export default function Player() { const controlsRef = useRef(); const { keys } = useContext(AppContext); const rapier = useRapier(); const controller = useRef(); const collider = useRef(); const rigidbody = useRef(); const camera = useRef(); const refState = useRef({ grounded: false, jumping: false, velocity: vec3(), }); useEffect(() => { const c = rapier.world.createCharacterController(0.1); c.setApplyImpulsesToDynamicBodies(true); c.setCharacterMass(0.2); controller.current = c; }, [rapier]); useBeforePhysicsStep((world) => { if (controller.current && rigidbody.current && collider.current) { const move_axis_x = +(keys.includes('KeyD')) - +(keys.includes('KeyA')); const move_axis_z = +(keys.includes('KeyW')) - +(keys.includes('KeyS')); const { velocity } = refState.current; const position = vec3(rigidbody.current.translation()); const movement = vec3(); const forward = new Vector3(); camera.current.getWorldDirection(forward); const left = new Vector3().crossVectors(forward, camera.current.up); movement.x += move_axis_z * world.timestep * _movespeed * forward.x; movement.z += move_axis_z * world.timestep * _movespeed * forward.z; movement.x += move_axis_x * world.timestep * _movespeed * left.x; movement.z += move_axis_x * world.timestep * _movespeed * left.z; if (refState.current.grounded) { velocity.y = 0; } else { velocity.y -= 9.81 * world.timestep * world.timestep; } movement.add(velocity); controller.current.computeColliderMovement(collider.current, movement); refState.current.grounded = controller.current.computedGrounded(); let correctedMovement = controller.current.computedMovement(); position.add(vec3(correctedMovement)); rigidbody.current.setNextKinematicTranslation(position); } }); return ( ); }