Correct, connections can be either manually disconnected (:Disconnect()
, .Connected
→ false). Moreover, the signal is going to disconnect once the object it is bound to is destroyed.
Consider the summarized example
local numberValue = Instance.new("NumberValue")
local connection; connection = numberValue.Changed:Connect(function(newValue)
print(newValue)
end)
task.spawn(function()
while numberValue do
numberValue.Value += 1
task.wait(1)
end
end)
task.wait(1)
numberValue:Destroy()
print(connection.Connected) --> false
(Side note: the reference to number value is not lost yet - number value base is still defined - so it won’t be subject to garbage collection until we set numberValue
to nil
and thus lose all (strong) reference.)
The CharacterAdded
will get disconnected once Player instance
is properly destroyed. Does the engine remove it automatically? It should, but to be on the safe side, I hook something like the following to my PlayerRemoving
connections.
game:GetService("Players").PlayerRemoving:Connect(function(player)
-- save data
-- destroy character when you don't need it anymore
task.wait(100) -- a reasonable wait time
player:Destroy()
end)
A useful announcement post regarding player:Destroy()
.
A small discussion other devs and I had regarding player and character removal, espeically character.
Some additional examples with characte resetting.
NumberValue outside character, not destroyed nor disconnected.
local PlayerService = game:GetService("Players")
local numberValues = {
Instance.new("NumberValue"), Instance.new("NumberValue")
}
task.spawn(function()
while true do
task.wait(1)
numberValues[1].Value += 1
numberValues[2].Value += 10
end
end)
PlayerService.PlayerAdded:Connect(function(player)
local n = 0
player.CharacterAdded:Connect(function(character)
n += 1
if n > 2 then return; end
numberValues[n].Changed:Connect(function(newValue)
print(newValue)
end)
end)
end)
NumberValue inside character, with commented code that destorys the character.
local PlayerService = game:GetService("Players")
local weakReferences = setmetatable({}, {__mode = "v"})
PlayerService.PlayerAdded:Connect(function(player)
local n = 0
player.CharacterAdded:Connect(function(character)
n += 1; local _n = n -- a private copy of n
weakReferences[_n] = Instance.new("NumberValue")
weakReferences[_n].Parent = character
weakReferences[_n].Changed:Connect(function(newValue)
print(newValue)
end)
while weakReferences[_n] do
weakReferences[_n].Value += 1
task.wait(1)
end
end)
--player.CharacterRemoving:Connect(function(character)
-- character:Destroy()
--end)
end)
In the second example, you’ll notice how .Changed
isn’t getting disconnected, which is still quite a strange phenomenon, compared to the very first example at the top of the post. Uncommenting the commented lines to eventually destory the character yields the expected result.