import { useFrame, useThree } from "@react-three/fiber"; import React, { useEffect, useState } from "react"; import * as CONSTANTS from "../../../types/world/worldConstants"; import { useCamMode, useToggleView } from "../../../store/builder/store"; import { useKeyboardControls } from "@react-three/drei"; import switchToThirdPerson from "./switchToThirdPerson"; import switchToFirstPerson from "./switchToFirstPerson"; import { detectModifierKeys } from "../../../utils/shortcutkeys/detectModifierKeys"; import { firstPersonCamera } from "./firstPersonCamera"; const CamMode: React.FC = () => { const { camMode, setCamMode } = useCamMode(); const [_, get] = useKeyboardControls(); const [isTransitioning, setIsTransitioning] = useState(false); const state: any = useThree(); const { toggleView } = useToggleView(); const [isShiftActive, setIsShiftActive] = useState(false); useEffect(() => { const handlePointerLockChange = async () => { if (document.pointerLockElement && !toggleView) { } else if (camMode === "FirstPerson" && !toggleView) { setCamMode("ThirdPerson"); await switchToThirdPerson(state.controls, state.camera); } }; document.addEventListener("pointerlockchange", handlePointerLockChange); return () => { document.removeEventListener("pointerlockchange", handlePointerLockChange); }; }, [camMode, toggleView, setCamMode, state.controls, state.camera]); useEffect(() => { const handleKeyPress = async (event: KeyboardEvent) => { if (!state.controls) return; const keyCombination = detectModifierKeys(event); if (keyCombination === "/" && !isTransitioning && !toggleView) { firstPersonCamera({ setIsTransitioning, state, camMode, setCamMode, switchToFirstPerson, switchToThirdPerson, }); } if (keyCombination === 'Shift') { setIsShiftActive(true); } }; const handleKeyUp = (event: KeyboardEvent) => { if (event.key === "Shift") { setIsShiftActive(false); } }; window.addEventListener("keydown", handleKeyPress); window.addEventListener("keyup", handleKeyUp); return () => { window.removeEventListener("keydown", handleKeyPress); window.removeEventListener("keyup", handleKeyUp); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [camMode, isTransitioning, toggleView, state.controls, state.camera, setCamMode]); useFrame(() => { const { forward, backward, left, right } = get(); if (!state.controls) return; if (camMode === "ThirdPerson" || !document.pointerLockElement) return; const speedMultiplier = isShiftActive ? 4 : 1; if (forward) { state.controls.forward(CONSTANTS.firstPersonControls.forwardSpeed * speedMultiplier, true); } if (backward) { state.controls.forward(CONSTANTS.firstPersonControls.backwardSpeed * speedMultiplier, true); } if (left) { state.controls.truck(CONSTANTS.firstPersonControls.leftSpeed * speedMultiplier, 0, true); } if (right) { state.controls.truck(CONSTANTS.firstPersonControls.rightSpeed * speedMultiplier, 0, true); } }); return null; }; export default CamMode;