How do I detect the Player?

Hello everyone!

I was working on the script which detects a player, when his tool touched something, and he receives some XP, but I got one problem.

script.Parent.Tool.Part.Touched:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
    local expPoints = player:findFirstChild("leaderstats")
    if expPoints ~= nil then
        local points = expPoints:findFirstChild("Exp")
        if points ~= nil then
            points.Value = points.Value + 10
        end
    end
end)

When I test out the game I receive this in the output:

Workspace.AwesomelyDeveloper.XP_Script:3: attempt to index local ‘player’ (a nil value)

Script is in the StarterPlayer>StarterCharacterScripts>XP_Script and here is the place of the tool:

Starter

local PlayersService = game:GetService("Players")
 
local function onTouch(hit)
    local player = PlayersService:GetPlayerFromCharacter(hit.Parent)
    local expPoints = player:findFirstChild("leaderstats")
    if expPoints ~= nil then
        local points = expPoints:findFirstChild("Exp")
        if points ~= nil then
            points.Value = points.Value + 10
        end
    end
end
 
script.Parent.Touched:connect(onTouch)

I tried using this script inside of the part in the workspace, so once I touch that part I receive some XP and it works pretty well, while the XP_Script inside of StarterCharacterScripts tells me that local ‘player’ is a nil value… Can someone fix this issue? Thanks.

3 Likes

I think the problem is that your code is working under the assumption that everything it touches must be a character of a Player.

Add a check if player exists before doing anything with that, because GetPlayerFromCharacter returns nil if the given instance does not belong to any player’s Character.

7 Likes
local function onTouch(hit)
    local player = PlayersService:GetPlayerFromCharacter(hit.Parent)
    if player then
        local expPoints = player:findFirstChild("leaderstats")
        if expPoints then
        local points = expPoints:findFirstChild("Exp")
        if points then
            points.Value = points.Value + 10
        end
    end
end
3 Likes
 local PlayersService = game:GetService("Players")

local function onTouch(hit)
    local player = PlayersService:GetPlayerFromCharacter(hit.Parent)
    if player then
        local expPoints = player:findFirstChild("leaderstats")
        if expPoints then
        local points = expPoints:findFirstChild("Exp")
        if points then
            points.Value = points.Value + 10
	        end
	    end
	end
end

script.Parent.Tool.Part.Touched:Connect(onTouch)

It doesn’t give an error anymore, but I am not receiving any XP.

I attempted the code you posted above to find any more errors and only changed the line script.Parent.Tool.Part.Touched:Connect(onTouch) to script.Parent.Touched so I could test with a brick and it worked fine with the leaderboard I set up though you might want to add a debounce

I tried script.Parent.HumanoidRootPart.Touched:Connect(onTouch) and it doesn’t work if I touch something with HumanoidRootPart…

Is this script inside of a player? I think you might be looking for something along the lines of this

HRP = Hit.Parent:FindFirstChild(“HumanoidRootPart”)

1 Like

I tried using print() method and looks like it prints in the output if print is here:

 local PlayersService = game:GetService("Players")

local function onTouch(hit)
    local player = PlayersService:GetPlayerFromCharacter(hit.Parent)
    print("Touched!")
    if player then
        local expPoints = player:findFirstChild("leaderstats")
        if expPoints then
        local points = expPoints:findFirstChild("Exp")
        if points then
            points.Value = points.Value + 10
	        end
	    end
	end
end

script.Parent:FindFirstChild("Tool"):WaitForChild("Part").Touched:Connect(onTouch)

If I place print() inside of other if’s it won’t print anything in the output.

1 Like
local function OnTouch(Hit)
	local Humanoid = Hit.Parent:FindFirstChild("Humanoid")
	if Humanoid then
		local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
		local LeaderstatsFolder = Player:WaitForChild("leaderstats")
		local ExpPoints = LeaderstatsFolder:WaitForChild("Exp")
		ExpPoints.Value = ExpPoints.Value + 10
	end
end

Tested this so it should work

3 Likes
local function onTouch(hit)
	local humanoid = hit.Parent:findFirstChild("Humanoid")
	local player = game.Players:GetPlayerFromCharacter(humanoid.Parent)
	print(player)
		if humanoid~=nil and player ~= nil then
			print("step1")
					print("Touched!")
       				local expPoints = player:findFirstChild("leaderstats")
					print("step2")
        				if expPoints then
							print("step3")
       			 			local points = expPoints:findFirstChild("Exp")
							print("step4")
     					    if points then
							print("step5")
          					points.Value = points.Value + 10
							print("step6")
	        			end
	   				end
				end
			end
		end
script.Parent.Touched:Connect(onTouch)

Test this? The prints were just to ensure that every step was running through you can delete them

2 Likes

It doesn’t work either. No errors in the output.

You did connect the OnTouch event didn’t you? As in

toolthing.Touched:Connect(OnTouch)

If you did, could you provide a place file so I can see what is happening?

(Doesnt have to be public, you could DM it if you wanted)

Test this:

local debounce = false
local cooldown = 5

local function onTouch(hit)
   if debounce == true then return end
   debounce = true

   local Humanoid = hit.Parent:FindFirstChild("Humanoid")
   if not Humanoid then -- if it touches accessories
      Humanoid = hit.Parent.Parent:FindFirstChild("Humanoid")
      if not Humanoid then 
          debounce = false 
          return 
      end
   end
   
   local Player = game.Players:GetPlayerFromCharacter(hit.Parent)
   local Leaderstats = Player:WaitForChild("leaderstats") -- fill in with the name of the leaderstats
   local ExpPoints = Leaderstats:WaitForChild("Exp") -- fill in the name of the what I think is IntValue
   ExpPoints.Value = ExpPoints.Value + 10
   
   wait(cooldown)
   debounce = false
end

script.Parent.Touched:Connect(onTouch) -- script should be parented to the part of the tool

I suspect debounce is required. Also check if it’s a LocalScript.
– Updated twice: Fixed the debounce issue after the function uses return.

It doesn’t print anything. It says that humanoid is a nil value for some reason :confused:

Is the script you are using within a tool? If so, is it a server script?

Can I be added to a team create or get the game file? I am testing this in my own game and it is working at the moment so I’m a little confuzled.

Tool is actually a joint to the StarterCharacter’s Right Hand.

:eye: Eyes open, the ‘Tool’ is a model. Holy smokes!

Also that the script is parented to StarterCharacterScripts. When a player joins, the script is in the model. Haha.

Please parent it to the respective part in the ‘Tool’ model you wish to attach the function with.

For some reason your script didn’t work. There are no errors in the output :confused:

1 Like

Please remember guys that the parent of a touched part can be nil, do not assume that the part has a parent.