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;