From 8295d6f0febfe8b8d327ec44a9ba9266b14ad1f0 Mon Sep 17 00:00:00 2001 From: min Date: Tue, 9 Jun 2026 18:09:45 +0300 Subject: [PATCH] =?UTF-8?q?fix(g7):=20=D1=81=D0=B8=D0=BD=D0=BA=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=B7=D0=B8=D1=86=D0=B8=D0=B9=20=D1=81=D0=BF=D0=B0=D0=B2?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=BD=D1=8B=D1=85=20=D1=87=D0=B0=D1=81=D1=82?= =?UTF-8?q?=D0=B5=D0=B9=20=D0=B2=20shim=20=D0=B4=D0=BB=D1=8F=20AABB-touche?= =?UTF-8?q?d-check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DynamicsManager._applyToMesh обновляет pm.instances[id].x/y/z, но Lua-shim кэширует Position в part._state.Position на момент создания. AABB-check видел кубы навечно в небе → касание не ловилось. Фикс: GameRuntime.tick собирает позиции всех спавненных динамических примитивов и шлёт в shim через api.updateSpawnedPos(id, x, y, z). Shim обновляет part._state.Position у соответствующего partById. --- src/editor/engine/GameRuntime.js | 20 ++++++++++++++++++++ src/editor/engine/lua/RobloxShim.js | 10 ++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/editor/engine/GameRuntime.js b/src/editor/engine/GameRuntime.js index f8fe371..b051df0 100644 --- a/src/editor/engine/GameRuntime.js +++ b/src/editor/engine/GameRuntime.js @@ -972,11 +972,31 @@ export class GameRuntime { } else if (state?.player) { realPos = { x: state.player.x, y: state.player.y, z: state.player.z }; } + // Собираем актуальные позиции спавненных динамических примитивов + // (id >= 800000) — нужно для AABB-touched-check в Lua-shim, чтобы + // ловить попадание игрока в падающий куб. + let spawnedPositions = null; + try { + const pm = this.scene3d?.primitiveManager; + if (pm && pm.instances) { + for (const [id, data] of pm.instances.entries()) { + if (id < 800000 || data.anchored !== false) continue; + if (!spawnedPositions) spawnedPositions = []; + spawnedPositions.push([id, data.x, data.y, data.z]); + } + } + } catch (_) {} for (const sb of this.sandboxes) { // Обновляем реальную позицию игрока для Lua-shim if (realPos && sb.api?.updatePlayerPos) { try { sb.api.updatePlayerPos(realPos.x, realPos.y, realPos.z); } catch (_) {} } + // Синк спавненных динамических примитивов + if (spawnedPositions && sb.api?.updateSpawnedPos) { + for (const [id, x, y, z] of spawnedPositions) { + try { sb.api.updateSpawnedPos(id, x, y, z); } catch (_) {} + } + } // Для скриптов с target — добавляем актуальную позицию self const stateForSb = sb.target ? { ...state, selfPosition: this._collectSelfPosition(sb.target) } diff --git a/src/editor/engine/lua/RobloxShim.js b/src/editor/engine/lua/RobloxShim.js index 6f92cf1..a883530 100644 --- a/src/editor/engine/lua/RobloxShim.js +++ b/src/editor/engine/lua/RobloxShim.js @@ -2185,6 +2185,16 @@ export function registerRobloxShim(lua, opts) { updatePlayerPos(x, y, z) { api._realPlayerPos = { x: +x, y: +y, z: +z }; }, + // Синхронизация позиций спавненных физических частей (падающие кубы). + // GameRuntime каждый кадр зовёт это с актуальными координатами от + // pm.instances — иначе наш AABB-touched-check считает позиции + // устаревшими (на момент создания) и не ловит касание. + updateSpawnedPos(id, x, y, z) { + const part = partById.get(Number(id)); + if (part && part._state && part._state.Position) { + part._state.Position = new RbxVector3(x, y, z); + } + }, // Доступ к ключевым объектам (для тестов и отладки) partById, localPlayer, humanoid, character, workspace, players, game, };