How to get the local player's character in a server script?

So I’m trying to get the player’s character and parts such as the root part and humanoid, but I don’t know where to start. I’ve tried looking at free models’ scripts, and making my own, but haven’t gotten any further. How should I do this?

Usually you get the Players character by using GetPlayerFromCharacter which gets the Player by looking at its Character,

Usually used with Touched Events

Example:

Example.Touched:Connect(function(part)
   local Player = game.Players:GetPlayerFromCharacter(part.Parent)
   if Player then
     print(Player)
   end

end)

Another way is with CharacterAdded

game.Players.PlayerAdded:Connect(function(player) -- player
player.CharacterAdded:Connect(function(character) -- character
-- code
end)
end)

Another way is with StarterCharacterScripts in which you use script.Parent

1 Like

How would I get this to trigger as soon as the player loads in, though? It sounds like through this method, they have to touch a certain thing.

This may help you with That situation

What this does is fire the PlayerAdded code when lets say the Player joins, the CharacterAdded comes in when the character is spawned in.

1 Like

I just tried this, and here’s my code:

local PathfindingService  = game:GetService("PathfindingService")
local enemyHum = script.Parent:WaitForChild("Humanoid")
local enemyRootPart = script.Parent:WaitForChild("HumanoidRootPart")
plrHum = nil
plrRootPart = nil

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		plrHum = character:WaitForChild("Humanoid")
		plrRootPart = character:WaitForChild("HumanoidRootPart")
	end)
end)

local enemyPath = PathfindingService:CreatePath()
enemyPath:ComputeAsync(enemyRootPart.Position, plrRootPart.Position)

when I ran the code, it said it was attempting to index nil with the position. What am I doing wrong?

local PathfindingService  = game:GetService("PathfindingService")
local enemyHum = script.Parent:WaitForChild("Humanoid")
local enemyRootPart = script.Parent:WaitForChild("HumanoidRootPart")

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
	   local plrHum = character:WaitForChild("Humanoid")
	   local plrRootPart = character:WaitForChild("HumanoidRootPart")

       local enemyPath = PathfindingService:CreatePath()
       enemyPath:ComputeAsync(enemyRootPart.Position, plrRootPart.Position)
	end)
end)

Try changing your code to this.

Like this:

game.Players.PlayerAdded:Connect(function(Player)
 --Player.Character (Remove the "--" and add per example :FindFirstChildOfClass to maybe see Humanoid.)
end)

But your code should be like this:

game.Players.PlayerAdded:Connect(function(Player)
	Player.Character:FindFirstChildOfClass("Humanoid").WalkSpeed = 0
	while task.wait(1) do
		Player.Character:FindFirstChildOfClass("Humanoid").WalkSpeed += 1
	end
end)

It errors, so it might not even work.

Ummm… No. You use that if you want to get the Player from the character model. The OP is asking how to get the character from the player.

@UBERsnosluoc
You can’t get LocalPlayer on the server, but you can do this:

local playerServer = game:GetService("Players")
local players = playerService:GetPlayers()
for _, player in pairs(players) do
	local char = player.Character
	-- Do something
end

The Player object has a property that points to the player’s character model. The name of that property is Character. You can’t use FindFirst on it because it’s a reference. If it’s datafilled, then the character exists in game.Workplace. If it’s nil, then it does not.

Here’s the documentation that supports this:

https://create.roblox.com/docs/reference/engine/classes/Player#Character

2 Likes

I tried using this in my code, but it doesn’t work. Any idea what I’m doing wrong?

-- Variables --
local PathfindingService  = game:GetService("PathfindingService")
local enemyHum = script.Parent:WaitForChild("Humanoid")
local enemyRootPart = script.Parent:WaitForChild("HumanoidRootPart")

local enemyPath = PathfindingService:CreatePath()

local playerService = game:GetService("Players")
local players = playerService:GetPlayers()
for _, player in pairs(players) do
	plrChar = player.Character
	enemyPath:ComputeAsync(enemyRootPart.Position, plrChar.Torso.Position)
end

local waypoints = enemyPath:GetWaypoints()

for i, waypoint in pairs(waypoints) do
	enemyHum:MoveTo(waypoint.Position)
end

Sometimes when attempting to get the Character of a player, especially if they’ve only just joined the experience, you will get nil. This is because the player’s Character model has not yet been created and parented to the workspace.

You can get around this issue using the Player.CharacterAdded event.

local Players = game:GetService("Players")

-- Assuming this code runs prior to any player joining the
-- experience. If it does not, you should use a combination
-- of Players.PlayerAdded and GetPlayers to ensure all
-- current and future players are targeted.

Players.PlayerAdded:Connect(function(player)
    local Character = if player.Character and player.Character.Parent
        then player.Character
        else player.CharacterAdded:Wait()

    -- Your code goes here.
end)

I recommend that you adopt a pattern that allows you to define the intended behaviour regarding attacking the player, but allowing you to switch it on and off when (or if) required.

1 Like

There’s a few issues with your code. First of all, you need to pick a player to move to. So you can pick a random character, the closest one, etc… The second issue is that the pathfinding service does not work like that. You have to setup two different events. Roblox has example code that you can use in their documentation.

To pick a random player, you can do something like this:

local playerService = game:GetService("Players")
local players = playerService:GetPlayers()
local player = players[math.random(1, #players)]

To pick the closest one, that is a bit more involved.

local playerService = game:GetService("Players")

-- Function returns the player, character model, and HumanoidRootPart that is
-- closest to the erp.
local function findTargetClosest(erp)
	local players = playerService:GetPlayers()
	local player
	local dist = math.huge
	for _, item in pairs(players) do
		local char = item.Character
		local hrp = char:FindFirstChild("HumanoidRootPart")
		if hrp == nil then
			continue
		end
		local xdist = (erp.Position - hrp.Position).Magnitude
		if dist > xdist then
			player = item
			dist = xdist
		end
	end
	local char = player.Character
	local hrp = char:FindFirstChild("HumanoidRootPart")
	return player, char, hrp
end 

To use that function, just call it with the enemy root part (or erp). Since you are targeting a player, you will need to track the position of the player and recompute the path if the player has moved significantly since the last time the path was recomputed. This is more or less a complete solution that I posted for someone else some time ago. You will need to adapt it to fit your needs.

1 Like