|
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 <></>; |
|
} |
|
|