I want to detect if an instance’s children get changed. It is a folder named “Tower” that gets changed when a timer runs out. I have tried using Changed(), but it doesn’t work. I’m wondering if GetAttributeChangedSignal() would work for it.
function setup_descendant_changed_listener(ancestor, callback)
l
local descendant_added_c
local function setup_changed_listener(child)
local changed_c = child.Changed:Connect(function(...)
callback(child, ...)
end)
local ancestry_changed_c
ancestry_changed_c = child.AncestryChanged:Connect(function()
if not child:IsDescendantOf(ancestor) then
ancestry_changed_c:Disconnect()
if changed_c.Connected then
changed_c:Disconnect()
end
end
end)
end
--Setup for existing descendants and any that are added later
descendant_added_c = ancestor.DescendantAdded:Connect(setup_changed_listener)
for _, d in pairs(ancestor:GetDescendants()) do
setup_changed_listener(d)
end
end
setup_descendant_changed_listener(game.Workspace.Tower, function(changed_child)
print( ("%s was changed!"):format(changed_child.Name) )
end)
Can’t test it right now but let me know if it has problems
It works all right but since there are lots of descendants of the children of the folder, (there are models inside the folder, and the models and a lot more descendants.) I would make it look for just children that are changed/added.
I see, here’s a version that only listens for children changed events:
function setup_child_changed_listener(parent, callback)
local changed_cs = {}
local function setup_changed_listener(child)
local changed_c = child.Changed:Connect(function(...)
callback(child, ...)
end)
table.insert(changed_cs, changed_c)
--Stop listening for Changed events if the child gets a different Parent
local ancestry_changed_c
ancestry_changed_c = child.AncestryChanged:Connect(function()
if not child.Parent == parent then
ancestry_changed_c:Disconnect()
if changed_c.Connected then
changed_c:Disconnect()
end
end
end)
end
--Setup for existing children and any that are added later
local child_added_c = parent.DescendantAdded:Connect(setup_changed_listener)
for _, d in pairs(parent:GetDescendants()) do
setup_changed_listener(d)
end
--Return a cleanup function that disconnects the callback from any Changed events
return function()
child_added_c:Disconnect() --Don't connect callback to any Changed event for future added children
--Stop listening for Changed events for current children
for _, c in pairs(changed_cs) do
if c.Connected then
c:Disconnect()
end
end
end
end
It also returns a cleanup function so you can stop listening to these events again. Here’s a test script I used:
local cleanup
cleanup = setup_child_changed_listener(game.Workspace.Part, function(child, ...)
print(child, ...)
if child.Name == "Stop" then
unbind()
end
end)
It prints every time a child of workspace.A changes, but if a child is renamed to “Stop” (or if something called “Stop” is added as a child), it stops printing.