fix(lua): __rbxl_player_x/y/z отдельные функции (wasmoon-userdata fix)

Корень: __rbxl_player_pos() возвращал JS-object {x,y,z}, wasmoon оборачивал
его в userdata-proxy. В Lua pos.x давал NaN. Конфетти спавнились с NaN.

Фикс: 3 отдельные функции __rbxl_player_x/y/z возвращающие числа.
В скрипте игры 2 используем их напрямую.
This commit is contained in:
min 2026-06-09 13:18:30 +03:00
parent ba648de09c
commit 96644ede15
2 changed files with 24 additions and 17 deletions

View File

@ -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) ===
-- Висит на невидимой зоне над зелёной площадкой.

View File

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