diff --git a/src/components/ViewerControls.tsx b/src/components/ViewerControls.tsx index 1fdff3b..8fddf5d 100644 --- a/src/components/ViewerControls.tsx +++ b/src/components/ViewerControls.tsx @@ -276,11 +276,11 @@ export function ViewerControls() { className="gap-2 h-9" onClick={() => { if (!walkMode) { - toast.info("Modo Caminhada: Use WASD para se mover e o mouse para olhar ao redor. Pressione ESC para sair."); + toast.info("Modo Caminhada: Use WASD para andar, Q/E para subir/descer e o mouse para olhar. ESC para sair."); } setWalkMode(!walkMode); }} - title="Modo primeira pessoa (WASD para andar)" + title="Modo primeira pessoa (WASD mover, Q/E subir/descer)" > diff --git a/src/components/three/ModelViewer.tsx b/src/components/three/ModelViewer.tsx index 575c701..ca3b726 100644 --- a/src/components/three/ModelViewer.tsx +++ b/src/components/three/ModelViewer.tsx @@ -1337,7 +1337,7 @@ function WalkControls() { const { camera } = useThree(); // eslint-disable-next-line @typescript-eslint/no-explicit-any const controlsRef = useRef(null); - const keys = useRef({ w: false, a: false, s: false, d: false, shift: false }); + const keys = useRef({ w: false, a: false, s: false, d: false, q: false, e: false, shift: false }); const initialized = useRef(false); useEffect(() => { @@ -1367,6 +1367,8 @@ function WalkControls() { if (e.code === 'KeyA') keys.current.a = true; if (e.code === 'KeyS') keys.current.s = true; if (e.code === 'KeyD') keys.current.d = true; + if (e.code === 'KeyQ') keys.current.q = true; + if (e.code === 'KeyE') keys.current.e = true; if (e.code === 'ShiftLeft' || e.code === 'ShiftRight') keys.current.shift = true; }; const onKeyUp = (e: KeyboardEvent) => { @@ -1374,6 +1376,8 @@ function WalkControls() { if (e.code === 'KeyA') keys.current.a = false; if (e.code === 'KeyS') keys.current.s = false; if (e.code === 'KeyD') keys.current.d = false; + if (e.code === 'KeyQ') keys.current.q = false; + if (e.code === 'KeyE') keys.current.e = false; if (e.code === 'ShiftLeft' || e.code === 'ShiftRight') keys.current.shift = false; }; window.addEventListener('keydown', onKeyDown); @@ -1408,8 +1412,15 @@ function WalkControls() { dir.normalize(); camera.position.addScaledVector(dir, speed * dt); } - // Always stick to exactly 1.7m above ground - camera.position.y = gridY + 1.7; + + // Vertical movement (Q / E) + if (keys.current.e) camera.position.y += speed * dt; + if (keys.current.q) camera.position.y -= speed * dt; + + // Clamp to prevent clipping through the ground + if (camera.position.y < gridY + 0.2) { + camera.position.y = gridY + 0.2; + } }); if (!walkMode) return null;