I'm having issues with cloning and transferring an item to the player's backpack using a server script.
To summarise, the script works fine - for a singular player that is. When the player clicks on a button in a GUI to purchase an item, a LocalScript is used for when the player clicks the button and fires a RemoteEvent to the corresponding server script which in turn clones the item and transfers it to the player's backpack. However, the usage of 'game.Players:FindFirstChildOfClass("Player").Backpack' is not very effective for a multiplayer server. This is because it gives the item to any player it notices first, hence the name. The usage of 'game.Players.LocalPlayer.Backpack' does not work either due to the whole 'LocalPlayer is a null value' despite being declared through a variable.
How would I go about replacing it 'game.Players:FindFirstChildOfClass("Player") so that when the player that purchases the item gets the item instead of being given to someone else?
I'm pretty sure there is an obvious solution but at this point I've had enough and need to make progress.
Thanks.
You miss the point of when :FindFirstChildOfClass()
is supposed to be used. The method is designed to find a child's ClassName called by the string you had provided in the parenthesis.
There isn't a point to me explaining how to use it since you don't need this to get the player server side (Which is what I think you want to do). Just know that by doing this, this function can return any player since multiple players in Player Service fall under the ClassName 'Player'.
Yes, you will need to use a remote event. What's good about a remote event is that it provides you with the player through the OnServerEvent
parameters when communicating from client to server.
local RS = game:GetService("ReplicatedStorage") local event = RS:WaitForChild("RemoteEvent") --example names local itemName = "Item" local function onButtonClicked() event:FireServer(itemName) --Let the server know the player clicked end script.Parent.MouseButton1Click:Connect(onButtonClicked) --Connection made if the local script was under some text button
Simple events made with a single :FireServer()
command. We also gave a parameter for the item bought. Now for the server side, the server needs to set up the connection whenever a client fires this event.
--server script in ServerScriptService local RS = game:GetService("ReplicatedStorage") local event = RS:WaitForChild("RemoteEvent") local function requestPurchase(player, itemName) print(player.Name.." has purchased item "..itemName) end event.OnServerEvent:Connect(requestPurchase)
Notice that in the OnServerEvent there are two parameters given. First is the player which is what the RemoteEvent (From client to server) ALWAYS provides. The rest are any arguments passed from the client which is just the 'itemName'. You can pass more datatypes through a RemoteEvent like this. There wasn't a need to go to the Player service and get the player from there.
The last thing you wanted was how to get an item to the player's backpack. In my example I had only printed the itemName and player name. This is as simple as using :FindFirstChild()
to get a copy of the tool you want inserted to the backpack.
local desiredTool = game.ServerStorage:FindFirstChild(itemName):Clone() desiredTool.Parent = player.Backpack
The rest is up to how you set it up. Let me know if I missed anything or you want something explained some more.