From 598b91bd9e72c5adf76bdb7d40c71ff9329dda5a Mon Sep 17 00:00:00 2001 From: min Date: Tue, 9 Jun 2026 10:41:49 +0300 Subject: [PATCH] =?UTF-8?q?fix(lua):=20inst.Parent=20=3D=20X=20=D0=B0?= =?UTF-8?q?=D0=B2=D1=82=D0=BE-=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D1=8F?= =?UTF-8?q?=D0=B5=D1=82=20=D0=B2=20parent.Children?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Корень бага: g1_main делал: ev = Instance.new('BindableEvent') ev.Parent = ReplicatedStorage Но Proxy 'set' просто писал t['Parent']=value, НЕ добавляя ev в ReplicatedStorage.Children. Поэтому скрипт монетки делал: ev = ReplicatedStorage:FindFirstChild('CoinCollected') -- nil! if ev then ev:Fire() end -- false, ничего не происходит HUD/звук не обновлялись. Фикс: Proxy.set теперь: 1) удаляет себя из старого parent.Children 2) пушит в новый parent.Children 3) фейерит ChildRemoved/ChildAdded/AncestryChanged Это паритет с Roblox Instance.Parent setter. --- src/editor/engine/lua/RobloxShim.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/editor/engine/lua/RobloxShim.js b/src/editor/engine/lua/RobloxShim.js index 415c353..9dc8639 100644 --- a/src/editor/engine/lua/RobloxShim.js +++ b/src/editor/engine/lua/RobloxShim.js @@ -394,7 +394,8 @@ function newInstance(className, name) { GetPropertyChangedSignal: m.GetPropertyChangedSignal, }; // Proxy: для unknown свойств возвращаем stub чтобы скрипты не падали. - return new Proxy(target, { + let proxyRef; + proxyRef = new Proxy(target, { get(t, prop) { // Существующее свойство всегда возвращаем как есть (включая методы) if (Object.prototype.hasOwnProperty.call(t, prop) || prop in t) { @@ -417,6 +418,27 @@ function newInstance(className, name) { return stub; }, set(t, prop, value) { + // Авто-управление иерархией при `inst.Parent = X`: + // 1) удаляем себя из Children старого Parent + // 2) пушим в Children нового Parent + // 3) фейерим ChildAdded/ChildRemoved + if (prop === 'Parent') { + const oldP = t.Parent; + if (oldP && oldP.Children) { + const i = oldP.Children.indexOf(proxyRef); + if (i >= 0) { + oldP.Children.splice(i, 1); + try { oldP.ChildRemoved && oldP.ChildRemoved.Fire(proxyRef); } catch (_) {} + } + } + t[prop] = value; + if (value && value.Children && value.Children.indexOf(proxyRef) < 0) { + value.Children.push(proxyRef); + try { value.ChildAdded && value.ChildAdded.Fire(proxyRef); } catch (_) {} + } + try { t.AncestryChanged && t.AncestryChanged.Fire(proxyRef, value); } catch (_) {} + return true; + } t[prop] = value; return true; }, @@ -426,6 +448,7 @@ function newInstance(className, name) { return true; }, }); + return proxyRef; } /**