From e26f85457845199a947ae673b563d62cb9d892c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=98=D0=9D?= Date: Sat, 30 May 2026 13:15:09 +0300 Subject: [PATCH] =?UTF-8?q?fix(player):=20=D0=BC=D0=B5=D0=BD=D1=8E=20?= =?UTF-8?q?=D0=B1=D0=BE=D0=BB=D1=8C=D1=88=D0=B5=20=D0=BD=D0=B5=20=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D1=80=D1=8B=D0=B2=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BE=D1=82=D0=BF=D1=83=D1=81=D0=BA=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=9F=D0=9A=D0=9C=20(orbit)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit React onLockChange в KubikonPlayer считал ЛЮБУЮ потерю pointer-lock за нажатие ESC и открывал меню. В third отпускание ПКМ (orbit-камера) тоже снимает lock → меню выскакивало на каждый поворот камеры. Теперь меню открывается только если lock потерян в perma-режиме (first/lockfirst/sideview/shiftLock) — там потеря lock = реальный ESC. В third отпускание ПКМ игнорируется. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/KubikonPlayer/KubikonPlayer.jsx | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/KubikonPlayer/KubikonPlayer.jsx b/src/KubikonPlayer/KubikonPlayer.jsx index c23dcf3..c4b6540 100644 --- a/src/KubikonPlayer/KubikonPlayer.jsx +++ b/src/KubikonPlayer/KubikonPlayer.jsx @@ -711,15 +711,25 @@ const KubikonPlayer = () => { const s = sceneRef.current; if (!s || !s._isPlaying) return; const locked = !!document.pointerLockElement; - // Lock потерян, мы НЕ в UI-cursor mode → пользователь нажал ESC - if (!locked && s.player && !s.player._uiCursorMode) { - // Синхронно ставим флаг — listener PlayerController сработает - // следующим и увидит true, не вызовет _onExitRequest. - s.player._uiCursorMode = true; - // Открываем меню в следующий тик (state-update React) - setChatOpen(false); - setTopMenuOpen(true); - } + if (locked || !s.player || s.player._uiCursorMode) return; + // Lock потерян. НЕ всякая потеря = ESC! В third-person отпускание + // ПКМ (orbit-камера) тоже снимает lock — это НЕ выход в меню. + // Меню открываем ТОЛЬКО если lock был «постоянным» (perma-режим: + // first/lockfirst/sideview/shiftLock) — там потеря lock = реальный ESC. + const p = s.player; + const permaLock = ( + p._cameraMode === 'first' || + p._cameraMode === 'lockfirst' || + p._cameraMode === 'sideview' || + p._shiftLock + ); + // _rmbHeld был выставлен при входе в lock; если ПКМ отпущена в third — + // это orbit-завершение, не меню. + if (!permaLock) return; + // Реальный ESC в perma-режиме → открываем меню. + p._uiCursorMode = true; + setChatOpen(false); + setTopMenuOpen(true); }; // capture-фаза, чтобы успеть раньше PlayerController document.addEventListener('pointerlockchange', onLockChange, true);