HumanoidRootPart nil in one area of script, but not the other?

I’m trying to get the players rootpart to set an attachment, but its not working for an unknown (to me) reason. I’m using the same line I use to define the root in a different function (same script) and that line works just fine there, but not here. I’ve tried player.Character:WaitForChild(“HumanoidRootPart”) and that gave the error below:

  18:01:40.857  TestService: Exception thrown in your RayHit event handler: ServerScriptService.Combat:52: attempt to index nil with 'WaitForChild'  -  Studio

Problem line

local function OnHit(player, cast, result)
	local root = player.Character.HumanoidRootPart
	local origin = root.Position

Working line

local function Shooting(player, energy, mousePosition)
	castParams.FilterDescendantsInstances = {player.Character}
	
	local root = player.Character.HumanoidRootPart
	local firepoint = root.Position

Error:

  17:52:16.744  TestService: Exception thrown in your RayHit event handler: ServerScriptService.Combat:52: attempt to index nil with 'HumanoidRootPart'  -  Studio
1 Like

You can’t call “HumanoidRootPart” from serverscript.

1 Like

The error you’re getting is that the player’s Character is nil and you’re trying to index that nil character with HumanoidRootPart. Check and make sure that the functions are receiving a player argument and not another type of value:

print(typeof(player))

That being said, don’t assume that a Character will exist or that a HumanoidRootPart will either.

local function foobar(player, ...)
    local character = player.Character
    if not character then return end

    local rootPart = character:FindFirstChild("HumanoidRootPart")
    if not rootPart then return end

This is some boilerplate I typically write on a number of my scripts when working in Immediate SignalBehavior to make sure that I’m not operating on invalid characters.

1 Like

Even you can do that.

local function OnHit(player, cast, result)
	local root = workspace:FindFirstChild(game.Players[player.Name]).HumanoidRootPart
	local origin = root.Position

	if not root then
		return;
	end
end
1 Like

Don’t know what you mean here, HumanoidRootPart is visible to the server. Additionally, why are you indexing the Workspace with the name of the player? If there’s an instance that bears the same name as a player this code may return incorrect results.

You shouldn’t be reinventing the wheel for the Character property. Character already holds a reference to the player’s character model so if you have the player object there’s no sense in indexing the workspace for the character and introducing an edge case into your code.

If player.Character doesn’t work, neither would indexing the workspace for it because the problem is that it doesn’t exist to begin with.

2 Likes

print(typeof(player)) is returning “table” which does not sound right at all, do you know what the cause of this would be?

Check the places where you call these functions and check the arguments you’re passing. You’ve only provided the functions not the way they’re called so beyond telling you to find where you’re calling them and what you pass to them, no I can’t really know why it happens to you. Not enough context for that.

1 Like

The function is being called through this line which is the last line in the script

caster.RayHit:Connect(OnHit)

When i print the player, it returns with

  18:24:26.242   ▼  {
                    ["Caster"] =  ▶ {...},
                    ["RayInfo"] =  ▶ {...},
                    ["StateInfo"] =  ▶ {...},
                    ["UserData"] = {}
                 }  -  Server - Combat:53

Changing the “player” arguement to the last arguement like this prints as a vector 3

local function OnHit(cast, result, player)
  18:25:31.602  -1262.4658203125, 1854.9401855469, -9745.01953125  -  Server - Combat:53

Is this FastCast? You might want to check the documentation, player is not a parameter of RayHit.

https://etithespir.it/FastCastAPIDocs/fastcast-objects/caster/#rbxscriptsignal-rayhitactivecast-raycastresult-vector3-instance

2 Likes

sorry i meant, you can’t call Character from server script

That’s not correct either. Character replicates across the client/server boundary. It’s set by the server during avatar loading and can be seen by both environments. Please do some research and/or testing so you can make more informed posts.

1 Like
local myPlayer = game.Players.LocalPlayer


local function OnHit(player)
	local root = player.Character.HumanoidRootPart
	
	local origin = root.Position
	
	return origin
end

for _, v in pairs(workspace:GetDescendants()) do
	if v:IsA("BasePart") then
		v.Touched:Connect(OnHit(myPlayer))
	end
end

Ah, I figured this was the case when i saw it was printing a table. Do you think I could set the atch0 position in a function where I can call the player arguement and then set atch1 in the function where I can call the result arguement and somehow connect a beam between the two?

1 Like

Your testing is wrong. Touched fires with the BasePart that physically intersected the part in question so you wouldn’t receive a player here. You need to check for the validity of a player with GetPlayerFromCharacter.

local function touched(part)
    local player = game:GetService("Players"):GetPlayerFromCharacter(part.Parent)
    if player then
        print(player)
    end
end

I’d prefer not to hijack this thread too far to call out incorrect code structuring but you do need to do some more research and testing before asserting false facts, please and thank you!

1 Like

alright np, i also solved for peoples their problems but at this time that was my bad, i even learnt from you additional informations, thank you.

1 Like

I don’t personally use FastCast that often or at all but it seems like you can make use of ActiveCast’s UserData table to store the player provided you’re holding it somewhere in the casting script. I don’t have full context here so again it’s pretty hard to make good suggestions other than showing you the documentation and ways you can use the documentation to your advantage.

Check out this post:

1 Like

Appreciate this, the datatable let me store attachment0 so I could use it in the other function :slight_smile:

1 Like