I have a script which is has an event connection from game.
The script is a plugin by the way.
The problem is that the child parameters seems to exist and I can index Name on it. But when I try child.Parent, that returns nil. Even if there is a parent, or multiple parents, it tends to print nil.
What am I doing wrong, the docs don’t seem to say anything about this issue.
local delete_connection = game.DescendantRemoving:Connect(function(child: Instance)
if not child.ClassName:find("Script") then return end
print(child.Parent)
local path = child.Name
local last_parent = child.Parent
while true do
if not last_parent or last_parent == game then break end
path = last_parent.Name .. "\\" .. path
last_parent = last_parent.Parent
end
backend:ScriptDeleted(nil, child)
end)
Because it says “immediately”, the signal getting fired and the descendant being removed are likely tasks next to each other in the instruction execution cycle.
It’s likely that your code is running after the parent has been set to nil because the priority of the instance’s parent getting set to nil is higher than the priority of your code.
Why do you need this? There may be a workaround.
What I suggested is not a fact; I took an educated guess based on the behaviour of the code and my knowledge.
I want to send a POST request from my plugin to a localhost server whenever you delete an object.
The path of the object is crucial (which is why I need to recursively look at the previous parent and get the path).
I have to agree with your educated guess but I do wish that there is a workaround for this.
By definition DescendantRemoving is fired before the parent is changed. Other tasks don’t resume until the current one yields. The code sample in the docs specifically prints the parent of the descendant being removed, so it’s not clear how that could be nil when there’s no yield before printing its parent.
It’s able to read through the child’s properties, but the parent(s) are nil.
Is there any other way in which I could get the parent though.
Since I don’t want to loop through every single script in the game and add attributes or whatever.
This is due to deferred signals. If you switch workspace.SignalBehavior to Default or Immediate, it should work as expected. By default, new Roblox games used Deferred mode, which will run your connected function at the end of the invocation cycle.
So, when DescendantRemoving is called, it defers the call to your function. During this deferred time, the descendant is removed. Once your function is called, it’s too late.
Also, you can use instance:GetFullName() to get a path, which should work better than building it with a loop. child:GetFullName():gsub("%.", "\\")
For whatever reason, workspace holds a bunch of game-level settings. These affect the whole place, not just workspace.
Because you’re writing a plugin, this actually becomes quite challenging, since some users will have different SignalBehavior settings. Your plugin shouldn’t be touching that property IMO. To be honest, I’d argue that this is a Roblox bug since the event is no longer performing in the manner that it is supposed to.