How to find HumanoidRootPart after death?

I need to loop over each character every second and I get the characters by doing this:

playerService.PlayerAdded:Connect(function(plr)
	table.insert(players, plr)
	table.insert(characters, plr.CharacterAdded:Wait())
end)

But, when the character dies, for some reason the script cannot find the HumanoidRootPart (i’m using waitforchild) when the respawntime is 0 after death, and if the player dies mid-script the script will throw an error.

Does anyone know:

  1. What is causing the HumanoidRootParts not to be found
  2. How to immediately break from a loop when the HumanoidRootPart is not found

Thanks for reading :slightly_smiling_face:

1 Like

If you want to loop through each player, do this:

local playerService = game:GetService("Players")
for i, v in pairs(playerService:GetPlayers()) do
	if v.Character then
		local hrt = v.Character:WaitForChild("HumanoidRootPart")
	end
end
1 Like

Because the human part, HumanoidRootPart, no longer exists. The now newly made when they respawn HumanoidRootPart is not defined anymore …

1 Like

what would be your work around?

Possibly a refresh on that variable when they respawn. I’m pretty sure that would work.

1 Like

Try this

player = game.Players.LocalPlayer
rootPart = nil

player.CharacterAdded:Connect(function(char)
      rootPart = char.HumanoidRootPart
end
1 Like

Are you trying to find the HumanoidRootPart in the newly spawned Character?

1 Like

This is a bit of speculation, but I see no reason why that wouldn’t work. Other than a few moments, it wouldn’t exist. You’d have to deal with that where it is being used in the script, too.

1 Like

Yeah, I think I could solve it by using a local script. I’ll update you tomorrow :slight_smile:

The problem is that the hroot doesnt exist anymore when the player dies but prob can fix that with local-to-server script

I am a bit confused with what you are trying to achieve.

If you are trying to keep track of all hrps in-game, here’s how you do it:
(server-side script)

local allHrps = {}
	
local players = game:GetService("Players")
players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(char)
		table.insert(allHrps, char.PrimaryPart)
	end)
	
	player.CharacterRemoving:Connect(function(char)
		for _, hrp in allHrps do
			if not hrp.Parent then
				table.remove(allHrps, table.find(allHrps, hrp))
			end
		end
	end)
end)
1 Like

Great, thanks! This does work in finding the hroots, but if a script was running, how would you immediately break from the loop if the specific char died (player.characterRemoving) (I am looping on all chars)?
For instance if in the middle of the loop the hroot gets removed and we try to get its position it will throw an error since it doesn’t exist.

1 Like

You can use if hrp.Parent then which checks if the HRP still exists.
Check it once when the loop for that hrp starts. If it goes through, you are good for that HRP.

Note that if you have any yields, such as wait(), you should check it again after the yield.

if hrp.Parent then
	-- do stuff
	wait(1)
	if hrp.Parent then
		-- do stuff
	else
		-- HRP no longer exists
	end
else
	-- HRP does not exist
end
1 Like

By using the command: break to exit the loop.

for i = 1, 10 do
    print(i)
    if i == 5 then
        break
    end
end

Got to love it when the answer to a question is part of the question.

1 Like

To be honest, you could just parent a script to the startercharacterscripts and then just get the humanoidrootpart by doing script.Parent:WaitForChild(“HumanoidRootPart”) and this will be done each time the character spawns (dies).

1 Like

Local Script right? Need it to be server side :(. All I really need is the position of the hroot but people could exploit that so I would need to double check that with the server script: but the player could die before the script finishes, and that would through an error.

I mean how can you run in parallel something that can check if the player’s parent is nil, and then stop the loop to make sure that the player doesn’t die before the script can check if it has to break. Check message 13 please for explanation :slight_smile:

My theory is that the hrp falls through the ground and gets destroyed.
Can you try anchoring the hrp or maybe setting the hrp.Cancollide to true?

1 Like

With something like this …

playerService.PlayerAdded:Connect(function(plr)
    table.insert(players, plr)
    local character = plr.CharacterAdded:Wait()
    if character then -- can check for if they exist by this being true. 
        table.insert(characters, character)
    end
end)

How is it possible for them to die within the second they respawn? Might want to think about adding time to that bubble or spawning them in a safe spot. Maybe you’re dealing with this problem in the wrong spot.

Hello!

Here’s an example of how you can modify your code to handle character removal and access the HumanoidRootPart :slight_smile:

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

local players = {}
local characters = {}

playerService.PlayerAdded:Connect(function(plr)
    table.insert(players, plr)
    plr.CharacterAdded:Connect(function(character)
        table.insert(characters, character)
        character:WaitForChild("HumanoidRootPart")
    end)
    plr.CharacterRemoving:Connect(function(character)
        for i, char in ipairs(characters) do
            if char == character then
                table.remove(characters, i)
                break
            end
        end
    end)
end)

I hope the code is working for you 100%, I’m not sure that this is the solution…But I tried atleast:)

  1. The reason the HumanoidRootPart is not being found is likely because the character model is being removed before you can access it. When a player’s character dies, it takes some time for the character model to be removed and respawned. During this time, the HumanoidRootPart may not be available.

  2. To immediately break from a loop when the HumanoidRootPart is not found, you can use the break statement. The break statement allows you to exit the loop prematurely and continue with the rest of your code.

for i, character in ipairs(characters) do
    local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
    if humanoidRootPart then
        -- HumanoidRootPart found, continue with your code
        -- ...
    else
        -- HumanoidRootPart not found, break from the loop
        break
    end
end
1 Like