diff --git a/src/editor/engine/WeaponSystem.js b/src/editor/engine/WeaponSystem.js index a4bf657..048d848 100644 --- a/src/editor/engine/WeaponSystem.js +++ b/src/editor/engine/WeaponSystem.js @@ -90,6 +90,18 @@ export class WeaponSystem { if (e.button !== 0) return; // Если UI-режим курсора — не стреляем (мышь работает по GUI) if (this.scene3d?.player?.isUiCursorMode?.()) return; + // Если курсор СВОБОДЕН (нет pointer-lock — обычно 3-е лицо) — стреляем + // ТУДА, КУДА КЛИКНУЛИ, а не в центр камеры. При pointer-lock курсор в + // центре экрана → используем прицел камеры (aim не задаём). + if (document.pointerLockElement !== canvas) { + const rect = canvas.getBoundingClientRect(); + const cx = (e.clientX != null ? e.clientX : 0) - rect.left; + const cy = (e.clientY != null ? e.clientY : 0) - rect.top; + if (cx >= 0 && cy >= 0 && cx <= rect.width && cy <= rect.height) { + this.setAimScreenPoint(cx * (canvas.width / rect.width), + cy * (canvas.height / rect.height)); + } + } this._mouseDown = true; this._tryFire(); }; @@ -97,14 +109,28 @@ export class WeaponSystem { if (e.button !== 0) return; this._mouseDown = false; }; + // При свободном курсоре (3-е лицо) запоминаем позицию мыши — чтобы + // авто-огонь при удержании ЛКМ продолжал стрелять в точку курсора. + const onMove = (e) => { + if (!this._mouseDown) return; + if (document.pointerLockElement === canvas) return; + const rect = canvas.getBoundingClientRect(); + const cx = (e.clientX != null ? e.clientX : 0) - rect.left; + const cy = (e.clientY != null ? e.clientY : 0) - rect.top; + if (cx >= 0 && cy >= 0 && cx <= rect.width && cy <= rect.height) { + this._holdAim = { x: cx * (canvas.width / rect.width), y: cy * (canvas.height / rect.height) }; + } + }; const onKey = (e) => { if (e.code === 'KeyR') this.reload(); }; canvas.addEventListener('mousedown', onDown); window.addEventListener('mouseup', onUp); + window.addEventListener('mousemove', onMove); window.addEventListener('keydown', onKey); this._listeners.push({ target: canvas, type: 'mousedown', fn: onDown }); this._listeners.push({ target: window, type: 'mouseup', fn: onUp }); + this._listeners.push({ target: window, type: 'mousemove', fn: onMove }); this._listeners.push({ target: window, type: 'keydown', fn: onKey }); // Регистрируем перед-кадровый хук для авто-стрельбы (если auto=true) @@ -583,7 +609,12 @@ export class WeaponSystem { // (для tap-to-shoot на мобиле). Точка применяется один раз. let hit = null; let ray; - const aim = this._aimScreenPoint; + // aim: разовый клик (_aimScreenPoint) или удержание по курсору (_holdAim, + // только когда курсор свободен — нет pointer-lock). + let aim = this._aimScreenPoint; + if (!aim && this._holdAim && document.pointerLockElement !== this.scene3d?.canvas) { + aim = this._holdAim; + } try { if (aim) { ray = this.scene.createPickingRay(aim.x, aim.y, null, camera);