Infinite yield possible after death (localscript inside of tool)

Hi, so I came across a weird thing - when equipping a tool, dying, then equipping it again, it throws an infinite yield possible warning.

image
Script:

local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")

print(humanoidRootPart)

This prints perfectly for the first time, but after you for example walk off the baseplate, it throws that warning and doesn’t print.

image

Is this a Roblox bug?

A solution I found to this:
Putting a wait(1) in the first line.

The solution is pretty bad though in my opinion, wait used in a situation like this is code-smell, isn’t it?

Is there anything else you can do? Do I really have to script my own StarterPack?

Thanks!

The warning occurs because the character instance is removed upon dying. There’s no fix to this other than doing this:

character.Humanoid.Died:Connect(function()
wait(seconds until humanoid spawns again)
print(humanoidRootPart)
end)
1 Like

I’m thinking the player’s backpack gets replaced before the player’s new character gets set, so you end up with a reference to the old character that is already destroyed.

You could try waiting for CharacterAdded to fire if the character is not parented to Workspace.

local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")

local character = player.Character
if not character or character.Parent ~= Workspace then
    character = player.CharacterAdded:Wait()
end

local humanoidRootPart = character:WaitForChild("HumanoidRootPart")

That might still not be it though, I’m not too sure.

1 Like

The problem is that you are referencing player.Character after the player’s character has been destroyed. After removing the problematic part, your code should look like this:

local player = game:GetService("Players").LocalPlayer

local character = player.CharacterAdded:Wait()

local humanoidRootPart = character:WaitForChild("HumanoidRootPart")

print(humanoidRootPart)
1 Like

Seems like that works, thanks.

Why does the character.Parent ~= Workspace go through though, isn’t character’s parent always workspace?

As far as I know, it gets destroyed after death and replaced by a new one → local character = player.Character or player.CharacterAdded:Wait() should work too, in case it’s nil (just got destroyed), it will wait for it?

I don’t really see how it could use the old character.

1 Like

Maybe Roblox changed something about the character loading procedure? When the old character is deleted, there will inevitably be some time when neither the old character nor new character is used, and I bet it would be more performant to keep the property set to the old character until the new character is created.

Although I’m even more sure this wouldn’t be a problem in the first place if Roblox just reloaded the player’s tools in after the character spawns.

1 Like

Oh, I understood it now.
The script will still think that character is there because the property holds that object but character.Parent will be nil, similar to this:

local instance = Instance.new("Part")
instance.Parent = workspace
instance.Name = "Hello"

instance:Destroy()

print(instance) --> "Hello"
print(instance.Parent) --> nil

Thanks a lot!

1 Like