DescendantRemoving fires immediately before the
Instance/Parent|Parent of a descendant of the
Instance changes such that the object is no longer a descendant of the Instance.
Instance/Remove|Remove change an object’s Parent to nil, so calling these on a descendant of an object will therefore cause this event to fire.
Since this event fires before the the descendant’s removal, the Parent of the descendant will be unchanged, i.e., it will still be a descendant at the time of this event firing. If the descendant is also a child of the object, It will also fire before ChildRemoved. There is no similar event called “DescendantRemoved”.
If a descendant has children, this event fires with the descendant first followed by its descendants.
The example below should help clarify how DescendantRemoving fires when there are several objects involved.
Instance/Remove|Removeon PartA would cause DescendantRemoving to fire on both ModelA and Model, in that order.
- Setting the
Instance/Parent|Parentof PartA to ModelB would cause DescendantRemoving to fire on ModelA but not Model (as Model would still be an ancestor of PartA).
Instance/Destroy|Destroyon ModelA would cause DescendantRemoving to fire multiple times on several objects:
- On Model with ModelA, PartA then FireA.
- On ModelA, with PartA then FireA.
- On PartA with FireA.
This event fires with the descendant object that is being removed. Attempting to set the
Instance/Parent|Parent of the descendant being removed to something else will fail with the following warning: “Something unexpectedly tried to set the parent of X to Y while trying to set the parent of X. Current parent is Z”, where X is the removing descendant, Y is the ignored parent setting, and Z is the original parent of X. Below is an example that demonstrates this:
workspace.DescendantRemoving:Connect(function(descendant) -- Don't manipulate the parent of descendant in this function! -- This event fires BECAUSE the parent of descendant was manipulated, -- and the change hasn't happened yet, i.e. this function fires before that happens. -- Therefore, it is problematic to change the parent like this: descendant.Parent = game end) local part = Instance.new("Part") part.Parent = workspace part.Parent = nil -- This triggers DescendantRemoving on Workspace: --> Something unexpectedly tried to set the parent of Part to NULL while trying to set the parent of Part. Current parent is Workspace.
The following example prints the name of any descendant as it is being removed from the Workspace:
workspace.DescendantRemoving:Connect(function(descendant) print(descendant.Name .. " is currently parented to " .. tostring(descendant.Parent)) end) local part = Instance.new("Part") part.Parent = workspace part.Parent = nil --> Part is currently parented to Workspace print(part.Parent) --> nil