How to access the "humanoidrootpart"

Hi,
Ive been making a snowy island and I wanted to detect if the player is in the water and then the start to lose health because the water is really cold. The issue is that I cant seem to access the Humanoid Root Part. Ive tried a WaitForChild:() but then I get and Infinite yield. This is a local script in starter player scripts and Im accessing the player using Players.LocalPlayer.

Code
local Player = game.Players.LocalPlayer
local root = Player.Character.HumanoidRootPart
local min = root.Position - (4 * root.Size)
local max = root.Position + (4 * root.Size)	
local region = Region3.new(min,max):ExpandToGrid(4)
local material = workspace.Terrain:ReadVoxels(region,4)[1][1][1]
	if material == Enum.Material.Water then
		print("under water")
	end

Thanks In Advance. :grinning:

14 Likes

So when you use the WaitForChild function it justs yields infinitely or is it the warning?

3 Likes

You can always do something like this:

local LocalPlayer = game:GetService("Players").LocalPlayer
function Update(dt)
   local Character = LocalPlayer.Character
   if not  (Character)  then
   return
   end
   local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
   if not (HumanoidRootPart) then
   return
   end
   local min = HumanoidRootPart.Position - (4 * HumanoidRootPart.Size)
   local max = HumanoidRootPart.Position + (4 * HumanoidRootPart.Size)	
   local region = Region3.new(min,max):ExpandToGrid(4)
   local material = workspace.Terrain:ReadVoxels(region,4)[1][1][1]
	if material == Enum.Material.Water then
		print("under water")
	end
end
game:GetService("RunService").Heartbeat:Connect(Update)

The way I see it is that you are trying to read the terrain voxels. My way might be the best way for you to get the HumanoidRootPart and do your reading voxel thing.

If this helps you, please accept it as a solution. Thanks.

p.s: you can bind it to whatever you like; Stepped, Renderstepped. This is just an example.

12 Likes

it yields infinitely when I do waitforchild

2 Likes

You could try this. The character is probably not loaded in yet, so we can use Player.CharacterAdded:Wait() to wait until it is loaded in.


local Player = game.Players.LocalPlayer
local character = Player.Character or Player.CharacterAdded:Wait()
local root = character:WaitForChild("HumanoidRootPart")
6 Likes

What do you mean by this it gets red underlined

1 Like

Oh, right. Fixed. I misspelled.

4 Likes

yeah it is not printing under water now but I guess you solved the original problem: accessing the root part

1 Like

Yeah, you might want to check your voxel reading code. If I have solved your problem, be sure to mark the post as a solution.

1 Like

I’ve discovered your issue.

The reason it’s required is because the Character is somewhat separate from the player.

I’m going to give you a scenario to describe what happens

-- Player Joins the game
local Player = game.Players.LocalPlayer -- Defines the player
local Character = Player.Character-- Attempts to grab the players character
-- Game loads in the character 

As you can see you’re attempting to refrence the Character before It’s been loaded in.
Throwing a :CharacterAdded:Wait() will fix this problem.

Another scenario of a potential problem.

-- Player Joins the game
local Player = game.Players.LocalPlayer -- Defines the player
Player.CharacterAdded:Wait()
local Character = Player.Character-- Grabs the current player model of the player
local HumanoidRootPart = Character.HumanoidRootPart

-- Player Dies and is given a new Character

Character.HumanoidRootPart.Transparency = 1 -- The Character that "Character" is referencing has been destroyed, and you'll need to get a new one.

The easy fix to this entire problem is just to throw it into a starterCharacterScript instead.

Local Scripts inside StarterCharacterScripts will load after the characters were added. This will fix the problem of the character dying, due to a new script being created on respawn. And you could easily reference the character with

script.Parent

Script location
image

After clicking play
image

I hope this helps, let me know if you have any questions.

Edit: Another easy fix would be to wrap your script around a CharacterAdded event.

local Player = game.Players.LocalPlayer

Player.CharacterAdded:Connect(function(Character)
	print(Character:WaitForChild("HumanoidRootPart").Name) -- HumanoidRootPart 
end)
3 Likes

well ok it works now @polill00 response seems interesting too, but it already works so ill try that method another time ill mark the solution now

@HanoPino

There is no reason to bind this to Heartbeat, this means the code will run 60 times a second. (or every frame)

While it does work, It’s unneeded.

1 Like

ok ill try your method as well

1 Like

Ah upon reflection it looks like @imtkl’s solution would be efficient. I didn’t take into account you’re not only trying to define HRP, but also detecting when they’ve gone underwater. I apologize :pensive:

1 Like