From d6a874c8a0328622f95817106856b53b9406148b Mon Sep 17 00:00:00 2001 From: min Date: Tue, 9 Jun 2026 19:59:38 +0300 Subject: [PATCH] =?UTF-8?q?fix(g15):=20=D0=BA=D0=BB=D0=B8=D0=BA=20=D0=B2?= =?UTF-8?q?=203-=D0=BC=20=D0=BB=D0=B8=D1=86=D0=B5=20=D0=BF=D0=BE=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BE=D1=80=D0=B4=D0=B8=D0=BD=D0=B0=D1=82=D0=B0=D0=BC=20?= =?UTF-8?q?=D0=BA=D1=83=D1=80=D1=81=D0=BE=D1=80=D0=B0,=20=D0=BD=D0=B5=20?= =?UTF-8?q?=D1=86=D0=B5=D0=BD=D1=82=D1=80=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit В 3-м лице курсор свободный. _handlePlayClick ВСЕГДА пикал центром экрана через _pickFromCenter — независимо от того где находится курсор. Поэтому клик мышкой по мишени не срабатывал — пик шёл из центра. Фикс: проверяем document.pointerLockElement: - locked (1-е лицо) → _pickFromCenter (прицел всегда в центре) - !locked (3-е лицо) → scene.pick(clickX, clickY) по реальной позиции курсора при клике. Убрал debug-логи. --- src/editor/engine/BabylonScene.js | 25 ++++++++++++++++++++++++- src/editor/engine/lua/RobloxShim.js | 12 ++---------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/editor/engine/BabylonScene.js b/src/editor/engine/BabylonScene.js index a7dc045..f16d81f 100644 --- a/src/editor/engine/BabylonScene.js +++ b/src/editor/engine/BabylonScene.js @@ -3271,7 +3271,30 @@ export class BabylonScene { } if (!this.gameRuntime) return; - const pick = this._pickFromCenter(); + // В pointer-lock (1-е лицо) курсор скрыт в центре — пикаем центром. + // В 3-м лице (свободный курсор) — пикаем по координатам клика. + const locked = (document.pointerLockElement === this.canvas); + let pick; + if (!locked && Number.isFinite(clickX) && Number.isFinite(clickY)) { + const pi = this.scene.pick(clickX, clickY, (mesh) => { + if (!mesh.isPickable) return false; + if (mesh === this._ghostMesh) return false; + if (mesh.name && mesh.name.startsWith('gridLine')) return false; + return true; + }); + if (pi?.hit) { + let m = pi.pickedMesh; + if (m?.metadata?._isBlockProto && this.blockManager) { + const proxy = this.blockManager.findProxyByPickInfo(pi); + if (proxy) m = proxy; + } + pick = { mesh: m, point: pi.pickedPoint, pickInfo: pi }; + } else { + pick = null; + } + } else { + pick = this._pickFromCenter(); + } const target = pick?.mesh ? this._meshToTarget(pick.mesh) : null; const point = pick?.point ? { x: pick.point.x, y: pick.point.y, z: pick.point.z } : null; // 1) Self-onClick — только если target есть diff --git a/src/editor/engine/lua/RobloxShim.js b/src/editor/engine/lua/RobloxShim.js index d90a0ea..e56720c 100644 --- a/src/editor/engine/lua/RobloxShim.js +++ b/src/editor/engine/lua/RobloxShim.js @@ -2173,27 +2173,19 @@ export function registerRobloxShim(lua, opts) { if (!p) return; const id = p.primId ?? p.target; const part = partById.get(Number(id)); - if (p.kind === 'click') { - // eslint-disable-next-line no-console - console.warn('[shim fireTargetEvent click] primId=', id, 'part=', !!part); - } if (!part) return; if (p.kind === 'touch' || p.kind === 'touched') { part.Touched.Fire(hrp); } else if (p.kind === 'untouch' || p.kind === 'untouched') { part.TouchEnded.Fire(hrp); } else if (p.kind === 'click') { - // ClickDetector создаётся лениво — стрельба по 3D-объектам. + // ClickDetector — стрельба по 3D-объектам. // Фейерим без аргумента (передача объектов в Lua через wasmoon // может крашить с null.then). try { const cd = part._clickDetector; - // eslint-disable-next-line no-console - console.warn('[shim click]', 'partId=', id, 'cd=', !!cd, 'sig=', !!cd?.MouseClick, 'conns=', cd?.MouseClick?.connections?.length); if (cd && cd.MouseClick) cd.MouseClick.Fire(); - } catch (e) { - console.warn('[shim click err]', e?.message || e); - } + } catch (_) {} try { if (part.Clicked) part.Clicked.Fire(); } catch (_) {}