| | import {useRef} from 'react'; |
| | import {useFrame} from '@react-three/fiber'; |
| | import {useController, useXR} from '@react-three/xr'; |
| | import * as THREE from 'three'; |
| |
|
| | const USE_HORIZONTAL = true; |
| | const USE_VERTICAL = true; |
| | const USE_ROTATION = true; |
| | const HORIZONTAL_AXIS = 2; |
| | const VERTICAL_AXIS = 3; |
| | const ROTATION_AXIS = 2; |
| | const SENSITIVITY = 0.05; |
| | const DEADZONE = 0.05; |
| |
|
| | |
| | |
| | |
| | export default function MovementController() { |
| | const xr = useXR(); |
| | const controller = useController('right'); |
| | const forward = useRef(new THREE.Vector3()); |
| | const horizontal = useRef(new THREE.Vector3()); |
| |
|
| | useFrame(() => { |
| | const player = xr.player; |
| | const camera = xr.player.children[0]; |
| | const cameraMatrix = camera.matrixWorld.elements; |
| | forward.current |
| | .set(-cameraMatrix[8], -cameraMatrix[9], -cameraMatrix[10]) |
| | .normalize(); |
| |
|
| | const axes = controller?.inputSource?.gamepad?.axes ?? [0, 0, 0, 0]; |
| |
|
| | if (USE_HORIZONTAL) { |
| | horizontal.current.copy(forward.current); |
| | horizontal.current.cross(camera.up).normalize(); |
| |
|
| | player.position.add( |
| | horizontal.current.multiplyScalar( |
| | (Math.abs(axes[HORIZONTAL_AXIS]) > DEADZONE |
| | ? axes[HORIZONTAL_AXIS] |
| | : 0) * SENSITIVITY, |
| | ), |
| | ); |
| | } |
| |
|
| | if (USE_VERTICAL) { |
| | player.position.add( |
| | forward.current.multiplyScalar( |
| | (Math.abs(axes[VERTICAL_AXIS]) > DEADZONE ? axes[VERTICAL_AXIS] : 0) * |
| | SENSITIVITY, |
| | ), |
| | ); |
| | } |
| |
|
| | if (USE_ROTATION) { |
| | player.rotation.y -= |
| | (Math.abs(axes[ROTATION_AXIS]) > DEADZONE ? axes[ROTATION_AXIS] : 0) * |
| | SENSITIVITY; |
| | } |
| | }); |
| |
|
| | return <></>; |
| | } |
| |
|