From 96644ede15356975eb53c60f8d42871990af209f Mon Sep 17 00:00:00 2001 From: min Date: Tue, 9 Jun 2026 13:18:30 +0300 Subject: [PATCH] =?UTF-8?q?fix(lua):=20=5F=5Frbxl=5Fplayer=5Fx/y/z=20?= =?UTF-8?q?=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D1=84?= =?UTF-8?q?=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20(wasmoon-userdata=20fix)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Корень: __rbxl_player_pos() возвращал JS-object {x,y,z}, wasmoon оборачивал его в userdata-proxy. В Lua pos.x давал NaN. Конфетти спавнились с NaN. Фикс: 3 отдельные функции __rbxl_player_x/y/z возвращающие числа. В скрипте игры 2 используем их напрямую. --- src/community/docsGamesBuildersLua.js | 14 +++----------- src/editor/engine/lua/RobloxShim.js | 27 +++++++++++++++++++++------ 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/community/docsGamesBuildersLua.js b/src/community/docsGamesBuildersLua.js index 0253683..fdd0591 100644 --- a/src/community/docsGamesBuildersLua.js +++ b/src/community/docsGamesBuildersLua.js @@ -171,18 +171,10 @@ finishEvent.Event:Connect(function() winSound:Play() __rbxl_show_text("Победа! Ты дошёл до финиша!", 5) -- Конфетти над игроком (паритет с JS game.scene.spawnParticles) - print("[g2] before pos call") - local pos = __rbxl_player_pos() - print("[g2] pos=", tostring(pos), "type=", type(pos)) - if pos then - print("[g2] pos.x=", tostring(pos.x), "pos.y=", tostring(pos.y)) - end - local px = (pos and pos.x) or 0 - local py = (pos and pos.y) or 6 - local pz = (pos and pos.z) or 33 - print("[g2] spawning particles at", px, py + 3, pz) + local px = __rbxl_player_x() + local py = __rbxl_player_y() + local pz = __rbxl_player_z() __rbxl_spawn_particles("confetti", px, py + 3, pz, 3, 3) - print("[g2] particles call returned") end)`, g2_finish: `-- === Скрипт финиш-зоны (Lua) === -- Висит на невидимой зоне над зелёной площадкой. diff --git a/src/editor/engine/lua/RobloxShim.js b/src/editor/engine/lua/RobloxShim.js index 8dcd536..7078249 100644 --- a/src/editor/engine/lua/RobloxShim.js +++ b/src/editor/engine/lua/RobloxShim.js @@ -1826,13 +1826,28 @@ export function registerRobloxShim(lua, opts) { count: Number(count) || 1, }); }); - // Позиция игрока для удобства (для confetti над головой и т.п.) - // Берётся из api.updatePlayerPos который GameRuntime обновляет каждый кадр. + // Позиция игрока для удобства — отдельные функции для x/y/z, чтобы + // wasmoon не оборачивал результат в userdata-proxy. + global.set('__rbxl_player_x', () => { + const p = api._realPlayerPos || hrp._position || { X: 0 }; + return Number(p.x ?? p.X) || 0; + }); + global.set('__rbxl_player_y', () => { + const p = api._realPlayerPos || hrp._position || { Y: 0 }; + return Number(p.y ?? p.Y) || 0; + }); + global.set('__rbxl_player_z', () => { + const p = api._realPlayerPos || hrp._position || { Z: 0 }; + return Number(p.z ?? p.Z) || 0; + }); + // Совместимость: __rbxl_player_pos() возвращает 3 числа (x, y, z). global.set('__rbxl_player_pos', () => { - try { - const p = api._realPlayerPos || hrp._position || { X: 0, Y: 0, Z: 0 }; - return { x: p.x ?? p.X, y: p.y ?? p.Y, z: p.z ?? p.Z }; - } catch (_) { return { x: 0, y: 0, z: 0 }; } + const p = api._realPlayerPos || hrp._position || { X: 0, Y: 0, Z: 0 }; + return { + x: Number(p.x ?? p.X) || 0, + y: Number(p.y ?? p.Y) || 0, + z: Number(p.z ?? p.Z) || 0, + }; }); // Достаём ссылку на Lua-функцию один раз; вызовы безопасны (не doStringSync) const luaResumeCo = lua.global.get('__rbxl_resume_co');