fix(g7): синк позиций спавненных частей в shim для AABB-touched-check

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.
This commit is contained in:
min 2026-06-09 18:09:45 +03:00
parent 462ee62a9a
commit 8295d6f0fe
2 changed files with 30 additions and 0 deletions

View File

@ -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) }

View File

@ -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,
};