Instance:Destroy
"Sets the Instance.Parent property to nil, locks the Instance.Parent property, disconnects all connections, and calls Destroy on all children. This function is the correct way to dispose of objects that are no longer required. Disposing of unneeded objects is important, since unnecessary objects and connections in a place use up memory (this is called a memory leak) which can lead to serious performance issues over time.
Tip: After calling Destroy on an object, set any variables referencing the object (or its descendants) to nil. This prevents your code from accessing anything to do with the object.
Instance:Destroy
does not set your reference to the instance to nil
. The instance and its descendants were destroyed, but that does not eliminate from memory entirely. You will have to erase your references to destroyed instances manually in order for them to be completely garbage-collected
On another note,
local currentCharacter = player.Character or player.CharacterAdded:Wait()
The above code is flawed. There is a fatal edge case (see last two paragraphs) with this code snippet’s usage in the context of LocalScripts under StarterGui. The edge case will cause you to develop a reference to a destroyed instance. I have some additional thoughts on the snippet, which you can hear more about from a pin I made in the HiddenDevs Discord server:
Unfold to learn more...
Forget about using
local character = player.Character or player.CharacterAdded:Wait()
In every case where this is necessary it’s got a fatal edge case (see last two paragraphs), and in virtually every other situation, aborting continuation if the character doesn’t exist is best. My argument stems from, say, activating an ability mid-death, or teleporting characters to a map. It wouldn’t be practical to propagate the ability activation into the next life, or to interrupt all characters from being teleported when one isn’t available. But say you wanted to catch the outliers anyway, well, you could either spawn a new thread for every player to use the snippet:
task.spawn(function()
local character = player.Character or player.CharacterAdded:Wait()
teleport(character)
end)
Or be more efficient in your design:
local character = player.Character
if character then
teleport(character)
else
player.CharacterAdded:Once(teleport)
end
Not every situation is practically resolved using that snippet, and in many cases, a resolution isn’t really needed.
If your script is in StarterCharacterScripts
, you can access the character as the script’s parent with guarantee; waiting for the character in this context would yield indefinitely. If your script is in StarterPlayerScripts
(which it is), you cannot survive off that snippet as scripts under that container are only executed once, which means your reference to the character will eventually become outdated. If you need the character more than once, you follow a modified workflow:
local character = player.Character
if character then
onCharacterAdded(character)
end
player.CharacterAdded:Connect(onCharacterAdded)