Tool in StarterPack showing Character.Parent = nil after respawning

Put this in a LocalScript inside a tool in StarterPack. Works the first spawn. After respawning, keeps printing nil.

local p = game.Players.LocalPlayer
local c = p.Character
if not c then
	p.CharacterAdded:Wait()
	c = p.Character
end
while c.Parent == nil do
	print("-nil")
	wait()
	--c.AncestryChanged:wait()
	--print("Char added to " .. c.Parent.Name)
end
local h = c:WaitForChild("Humanoid")
--h:WaitForChild("Animator")
--local an = h:LoadAnimation(script.Anim)
print("Done")
--[[script.Parent.Equipped:Connect(function()
	--an:Play()
end)

script.Parent.Unequipped:Connect(function()
	--an:Stop()
end)]]
1 Like

This is not unexpected behaviour, it’s currently an edge case related to characters. The current ordering of avatar loading events is set up in such a way that CharacterAdded can fire before the character is parented to the workspace. There was an update that would’ve fixed this but it’s been deferred for a whole year now.

See Avatar Loading Event Ordering Improvements for more information.

I know, and my script waits indefinitely for Character to be added to workspace. The reason I am confused is Character.Parent remains nil.

Oh, I see the issue. It seems more like you’re running into a timing issue which again is still a product of faulty avatar loading events ordering. Please bother Roblox to get it in already.

I added a bit of extra code in the sample and tried running it. As I had suspected, comparing the data I attached to the character for the first time and checking it on respawn showed that the old character is still being referenced by the LocalScript.

local CollectionService = game:GetService("CollectionService")
local HttpService = game:GetService("HttpService")
local p = game.Players.LocalPlayer
local c = p.Character
if not c then
	p.CharacterAdded:Wait()
	c = p.Character
end
CollectionService:AddTag(c, HttpService:GenerateGUID(false))
while c.Parent == nil do
	print("-nil")
	print(unpack(CollectionService:GetTags(c)))
	wait()
	--c.AncestryChanged:wait()
	--print("Char added to " .. c.Parent.Name)
end
local h = c:WaitForChild("Humanoid")
--h:WaitForChild("Animator")
--local an = h:LoadAnimation(script.Anim)
print("Done")
print(unpack(CollectionService:GetTags(c)))
--[[script.Parent.Equipped:Connect(function()
	--an:Play()
end)

script.Parent.Unequipped:Connect(function()
	--an:Stop()
end)]]

Replace your code with this and check what GUID is printed to the console. You’ll notice that you get one when you first spawn and then when the while loop is running, it prints that same initial GUID out to the console from the old character.

Simply refreshing the variable provided me with a degree of success in resolving this, although there was still one iteration (frame) where the character is registered as the old one. In the while loop, above or below the wait, add in c = p.Character and it’ll stop infinitely printing nils.

1 Like

Thanks, both adding a wait() after CharacterAdded or at the start of the script works as well but the issue was definitely the old character being registered.