Hi, I’m trying to make a shop system. I have a script in ServerScriptService, but I don’t know how to address the players gui. The script is shown below.
local gui = game.Players.LocalPlayer:WaitForChild("PlayerGui"):WaitForChild("ScreenGui")
local player = game.Players.LocalPlayer
local playerStats = player:WaitForChild("leaderstats")
local playerGold = playerStats:WaitForChild("Gold")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent1")
local Owned = gui.Shop.Stats.Frame.LongStick.Owned
Owned.Value = false
local function purchasFunc(player, item)
if playerGold.Value >= 100 and Owned.Vlaue == false then
playerGold.Value = playerGold.Value - 100
Owned.Value = true
end
end
remoteEvent.OnServerEvent:Connect(purchasFunc)
If I did local gui = game.StarterGui.ScreenGui etc. then it would change the gui for everyone. (I think)
You can’t access LocalPlayer from the server. This only works in LocalScripts. That’s going to be the cause of your error.
More specifically (not the cause of your error, but still a concern), you shouldn’t be trying to update user interfaces from the server anyway. It makes for slow, unresponsive user interfaces and is poor practice. Read more about best practice on this article about the Client-Server Model
When the player buys the thing from the shop I want a boolValue to be set to true. Would I send a remote function back to the player to change the boolValue to true?
The recommended way to do something like that is through a client-server model (what I linked). I’d read it to get a good impression of how to do this kind of thing in the future.
Example pseudocode:
-- PirateServer.lua (Server Script)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
RemoteEvent.OnServerEvent:Connect(function(Player, Type, Item)
if Type == "Buy" then
if Item == "Vitamin C" and Player.Coins.Value >= VitaminCPrice then
-- Set Values
Player.HasScurvy.Value = false
Player.Coins.Value = math.max(Player.Coins.Value - VitaminCPrice, 0)
RemoteEvent:FireClient(Player, Player.Coins.Value)
end
end
end)
-- PirateClient.lua (LocalScript)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
RemoteEvent.OnClientEvent:Connect(function(Coins)
print(("Arr! I now have %i coins!"):format(Coins))
CoinsValue.Text = ("$%i"):format(Coins)
end)
BuyButton.MouseButton1Click:Connect(function()
RemoteEvent:FireServer("Buy", "Vitamin C")
end)
Here, the Client runs the interface, and the server handles the security & processing
I’m trying to update the player’s value in the ServerScript but it says I’m trying to index nil with 'WaitForChild`
local player = game.Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent1")
local playerStats = player:WaitForChild("leaderstats")
local playerGold = playerStats:WaitForChild("Gold")
local function purchasFunc(player, item)
if playerGold.Value >= 100 and player.Owned.Value == false then
playerGold.Value = playerGold.Value - 100
end
end
remoteEvent.OnServerEvent:Connect(purchasFunc)
Then you could fire a RemoteEvent to the server when a player buys an item, and then, when that event is fired, fire another RemoteEvent to all clients by using the RemoteEvent:FireAllClients() function.
You can’t call LocalPlayer on ServerScripts
I assume you already make use of a datastore system, you could create a table system in a ModuleScript in ServerScripts/ServerStorage and create a function with the player and amount argument to add/reduce money from their balance.
As I stated in my original post, you can’t reference “LocalPlayer” on the server. Think about it - the Server doesn’t have a “Local Player” - only the client.