diff --git a/src/editor/engine/lua/RobloxShim.js b/src/editor/engine/lua/RobloxShim.js index 122086d..6f92cf1 100644 --- a/src/editor/engine/lua/RobloxShim.js +++ b/src/editor/engine/lua/RobloxShim.js @@ -2038,6 +2038,38 @@ export function registerRobloxShim(lua, opts) { fireHeartbeat(dt) { try { HEARTBEAT_SIGNAL.Fire(dt); } catch (_) {} try { STEPPED_SIGNAL.Fire(performance.now() / 1000, dt); } catch (_) {} + // Авто-детект Touched на спавненных частях (id >= 800000): + // BabylonScene._detectTouchEvents срабатывает только для скриптов + // с явным target. Спавненные через __rbxl_spawn_part примитивы + // (падающие кубы, снаряды) Babylon не знает, поэтому делаем + // AABB-check игрок↔part прямо в shim каждый кадр. + try { + const pp = api._realPlayerPos; + if (!pp) return; + const phw = 0.4, phh = 0.9, phd = 0.4; + for (const [id, part] of partById.entries()) { + if (id < 800000) continue; + if (!part || part.Destroyed) continue; + if (!part.Touched || part.Touched.connections.length === 0) continue; + const pos = part._state?.Position; + const size = part._state?.Size; + if (!pos || !size) continue; + const hw = size.X / 2 + 0.1; + const hh = size.Y / 2 + 0.1; + const hd = size.Z / 2 + 0.1; + const overlap = + pp.x + phw > pos.X - hw && pp.x - phw < pos.X + hw && + pp.y + phh > pos.Y - hh && pp.y - phh < pos.Y + hh && + pp.z + phd > pos.Z - hd && pp.z - phd < pos.Z + hd; + if (overlap && !part.__lastTouching) { + part.__lastTouching = true; + try { part.Touched.Fire(hrp); } catch (_) {} + } else if (!overlap && part.__lastTouching) { + part.__lastTouching = false; + try { part.TouchEnded.Fire(hrp); } catch (_) {} + } + } + } catch (_) {} }, fireTargetEvent(p) { if (!p) return;