Nil player help (Newbie)

So I am trying to learn scripting and I’m attempting to create a mock game to learn with.
The problem below is:

I created a block that when touched, removes the players previous weapon(Tool) and purchases a new one and puts it in their Backpack.

The way I have tried to do this is by creating a Part with a Touched event and this script inside:

It fires a BindableEvent (“buyWeapon”) which is connected to this Script inside ServerScriptService:

The error that occurs is it seems the server is finding the player as nil. Attached below:

image

I believe I am not correctly sending the player over to the buy script/function.

If anyone knows how to solve this please help.

Hey there!
You are trying to get a LocalPlayer from ServerScript, which won’t work. Try removing 1st line in the 2nd script, you provided (the server sided one) and tell us the results.

You cannot get LocalPlayer in a regular script. You should be able to do all of this on the server anyway, assuming you are just awarding a player a sword when they touch a part, and not prompting a GUI.

No need for remotes in that case

Oops, I accidently wrote remoteevent but i meant bindableevent.
I used two server scripts for this.

What you could do to get the players is use the GetPlayerFromCharacter() method like so:

player = game.Players:GetPlayerFromCharacter(hit.Parent)

and remove

local player = game.Players.LocalPlayer

from the scripts.

Also use a capital F in buyWeapon:Fire

I replaced it like you said and put them inside the function because it couldn’t find hit until the function started (I guess).

and got this error:
image

Here is how i added it into the scripts:


  1. You don’t need to send hit to the other script.
  2. Since you sent player to the second script, player is already defined, no need to define it again.

GetPlayerFromCharacter is a function of the player service (game:GetService(“Players”)), you input the player’s character as the first argument and if it’s a player’s character it returns the player instance else nil.

so that’s one issue out of the way let’s address the next one, you’re checking if hit.Parent has a child named “Humanoid” which is completely fine but you’re assigning the value of the variable “player” before that and you don’t even use that variable outside of that if statement so move that in after you fix it.

Another thing that’s small but better “safe than sorry”, instead of using a wait(2) as a debounce just set 1 variable named “lastUsed” and it’s value will be tick(), each time .Touched is fired check if tick() - lastUsed is lower than 2, if so then return (aka don’t do anything) else run the code (that way it’s more precise and I guess better in general).

EDIT : I didn’t see the second screenshot so I’ll address the issues in it too~
The GetPlayerFromCharacter issue, already talked about so moving on.

WaitForChild - The way you’re using WaitForChild is horrible, you’re waiting for an object that’s named “Tool” under the character (which wouldn’t be the case if the player wasn’t holding their tool), same thing with the line below it so consider doing the following :

Instead of using WaitForChild use the function “FindFirstChildOfClass”, iirc the player can only hold one tool at a time, if you’re checking if they’re holding a tool then FindFirstChildOfClass would be the best choice to use, the first argument is the class name which is “Tool” in your use case.

Another thing I wanted to point out is your characterTool and backpackTool variables, you can make those into 1 variable using “or”.

local foundTool = player.Character and player.Character:FindFirstChildOfClass("Tool") or player.Backpack:FindFirstChildOfClass("Tool")
if foundTool then
   foundTool:Destroy()
end

Though please do keep in mind that FindFirstChildOfClass searches for the first object with the inputted class name not “name”, so if you’re specifically searching for “Tool” then use FindFirstChild.

You’re right, my bad. It should be game.Players:GetPlayerFromCharacter(hit.Parent) instead.

1 Like