Position is not a valid member of Player

I honestly don’t know what’s going on. I made a local script that sends LocalPlayer through a RemoteEvent. However, when getting the position of the HumanoidRootPart for the magnitude, I get an error: Position is not a valid member of Position

The code that I use is this (a script in ServerScriptService):

copyKeyGUI.OnServerEvent:Connect(function(player, item)
	local GUIPresent = player.PlayerGui:FindFirstChild("keyGUI")
	local magnitude = (item.Position - player.Character.HumanoidRootPart.Position).Magnitude
	if (magnitude < distance) and GUIPresent.Adornee ~= item then
		local GUI = keyGUI:Clone()
		GUI.Adornee = item
		GUI.Parent = player.PlayerGui
	end
end)

I’m certain that it has nothing to do with my LocalScript (hopefully) because when I do print(player) on the first line of the function, it prints out my username. I hope you could help me out with this!

What exactly is the “item” parameter you are passing to the Server?

1 Like

What is “item”?
Can’t you just send the position of the item instead?

1 Like

Item is what’s returned on this on the LocalScript:

function searchTool()
	for i, v in pairs(itemlist:GetChildren()) do
		local magnitude = (v.Position - Player.Character.HumanoidRootPart.Position).Magnitude
		if magnitude < distance then
			return v
		end
	end
end

item = searchTool() etc etc.

I’m trying to recheck if the player is within reach to avoid any problems.

I haven’t checked if item that is being sent to the script is not problematic. I will have to check on that now.

Mind telling me what item is then?
EDIT: Already provided

Try printing “item” on the server end of things when the remote event is called, and see what it spits out.

I recently checked and something must have went wrong in my local script.

I did this code:

print(item)
print(player)

and both came out my username. I’m not sure if this is the root of the problem but I’ll troubleshoot into this.

1 Like

You shouldn’t check this on the client-side.
Do all checks on the server.

Also, use ipairs over pairs when looping through arrays, as itemlist:GetChildren() returns an array.

EDIT: If the itemlist only exists on the client, its reference on the server will be nil.

1 Like

Hey, what’s in itemlist?

This might take me a while since I haven’t really studied ipairs but I’ll give it a try

itemlist is a folder that contains a part which is supposed to be the item being sent into the server-side script. However, my username came out instead of the part inside the folder

Actually, “ipairs” vs “in pairs” doesn’t matter in this instance. This is not the source of the problem.

1 Like

That’s not what I’m saying, I’m simply saying pairs does not belong when looping through arrays, as ipairs is designed to do that, and it is faster.

pairs is used for dictionaries.

2 Likes

Here’s my full script since it isn’t that long yet so yeah:

LocalScript (located in StarterGui)

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Player = Players.LocalPlayer
local keyGUI = ReplicatedStorage.GUI.keyGUI
local copyKeyGUI = ReplicatedStorage.Events.copyKeyGUI
local destroyKeyGUI = ReplicatedStorage.Events.destroyKeyGUI
local itemlist = workspace.OBJ

local distance = 15


function searchTool()
	for i, v in pairs(itemlist:GetChildren()) do -- change later
		local magnitude = (v.Position - Player.Character.HumanoidRootPart.Position).Magnitude
		if magnitude < distance then
			return v
		end
	end
end

while wait(0.1) do
	local item = searchTool()
	if item then
		local checkGUI = item:FindFirstChild("keyGUI")
		local char = Player.Character
		local magnitude = (item.Position - char.HumanoidRootPart.Position).Magnitude
        if (magnitude < distance) and not checkGUI and char then
		    copyKeyGUI:FireServer(Player, item)
	    else
		    local GUI = Player.PlayerGui:FindFirstChild("keyGUI")
		    if GUI and checkGUI and char then
			    destroyKeyGUI:FireServer(Player, item)
		    end
		end
	end
end

Script (located in ServerScriptService):

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local copyKeyGUI = ReplicatedStorage.Events.copyKeyGUI
local destroyKeyGUI = ReplicatedStorage.Events.destroyKeyGUI
local keyGUI = ReplicatedStorage.GUI.keyGUI

local distance = 15

copyKeyGUI.OnServerEvent:Connect(function(player, item)
	print(item)
    print(player)
	local GUIPresent = player.PlayerGui:FindFirstChild("keyGUI")
	local magnitude = (item.Position - player.Character.HumanoidRootPart.Position).Magnitude
	if (magnitude < distance) and GUIPresent.Adornee ~= item then
		print("detected")
		local GUI = keyGUI:Clone()
		GUI.Adornee = item
		GUI.Parent = player.PlayerGui
	end
end)

destroyKeyGUI.OnServerEvent:Connect(function()
	print("destroyed")
end)

You are sending the player instance to the server, but it’s already there. That’s why both arguments are your player.

What you’re basically doing:
ServerEvent(Player, Player, Item, …)

When it should be
ServerEvent(Player, Item, …)

3 Likes

Sorry I don’t really understand. I’m trying to send localplayer to the server script since I need it for security. Please enlighten me about this!

This is correct. When Fire()ing a remote event to the server, the local player parameter is added by default before any other parameters. If you do as Syclya said, your problem should be solved.

1 Like

The player is automatically sent to the server (the one triggering it).

1 Like

This is the first time I’ve heard of this. I’ll be running some tests to see if it works.

How do I define this in my serverscript though?

FireServer(item)
OnServerEvent(Player, item)

1 Like