How do you get the Player in a normal script?

I am having trouble trying to get the player from a normal script.

When I use it as Players.LocalPlayer and then try to use it to get a leaderstat I keep getting an error saying attempt to index nil with 'WaitForChild' or attempt to index nil with 'Character' the same thing happens if I try to use player as a function
I have no problem using this in a local script but always in a normal script.

Script:

--[[ Services ]]
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

--[[ References ]]
local GameItems = ReplicatedStorage.GameItems

local EquipButton = script.Parent
local LevelRequirment = script.Parent.Level
local WeaponName = script.Parent.Item

local function GiveItem(Player)
	local Character = Player.Character or Player.CharacterAdded:Wait()
	local leaderstats = Player:WaitForChild("leaderstats")
	local Level = leaderstats:WaitForChild("Level")

	if Level.Value >= LevelRequirment.Value then
		if GameItems:FindFirstChild(WeaponName.Value) then
			GameItems[WeaponName.Value]:Clone().Parent = Player.Character
		end
	end
end

EquipButton.MouseButton1Click:Connect(GiveItem)
1 Like

use game.Players:GetPlayerFromCharacter() (for .Touched based events)
you can also connect it to a remote event and put the functions inside there, this way you would be able to use local player object.

You can also write these functions inside a LocalScript and use remote events to communicate with the server.

So if I wanted to get a Player from a normal script i would have to use a RemoteEvent?

you don’t have to do it with a remote event, that is a option, not a necessity

So would I still use Players.LocalPlayer to get the player without GetPlayerFromCharacter() for a touched event?

You can’t do Players.LocalPlayer inside Server scripts, but what you can do is to use RemoteEvents

LocalPlayer is only used in local scripts

You can use PlayerAdded function to get the player.

sometimes scripts are located as a descendant of the player and you can use FindFirstAncestorOfClass

Would be used like this? FindFirstAncestorOfClass("Player")

Looks like you’re trying to use some sort of UI piece to do something. Is it on the screen or on a surface?

It is on the screen and it is a TextButton.

Utilize a LocalScript to manage the UI aspect of clicking it and stuff. It will fire a remote located in ReplicatedStorage which in turn will signal to the server to do the GiveItem function. Sanity checks are required such as those if statements included in it. The first parameter from the signal will always be player, do not fire the player(whoever is firing it) object reference through the remote.

yes but for your case you can’t use this

But in general i would use a remoteevent or remotefunction to get the player in a server script?

I think it is a general rule for GUIs to be handled by the client-side only. So RemoteEvents are the way to go. After that, leaderstats and weapon giving must be handled by the Server.

You can get the player that is firing the Remote Event. It is the first parameter passed in for the function given to RemoteEvent.OnServerEvent:Connect(). More information: Remote Functions and Events (roblox.com).

I understand a little I’m going to try my best to learn remote events and functions.