I'm working on a shop GUI that opens up whenever a player clicks an NPC. I've got one problem, though. The GUI opens up fine, but when the button is clicked by the player, the output says "Attempt to index nil with 'Name'." Here's the code in each button the player clicks (in the GUI) to buy a product:
script.Parent.MouseButton1Click:Connect(function(plr) local stats = game.ServerStorage.PlayerMoney:FindFirstChild(plr.Name) local tool = game.ServerStorage:FindFirstChild("Copper Sword") local price = 350 if stats.Value >= price then tool:Clone().Parent = plr.Backpack stats.Value = stats.Value - price end end)
Please help me if you know the answer. The error occurs on Line 2. Thanks!
MouseButton1Click does not take in any parameters. How I found that out was by going to GuiButton's wiki page and then looked for the MouseButton1Click event in the events section
Since you're using a local script, What you can instead do is get the player by saying:
local player = game.Players.LocalPlayer
Another issue with your script is that you can't view the server storage from the client. If you press play and look at the explorer, you'll see you can't see the contents of ServerStorage. You CAN see ReplicatedStorage though so if you'd like you can put the PlayersMoney/Copper Sword there instead.
You also can't change stat's value from the client. Aside from the player's movement, any changes you make to the game from the client won't change on the server, so you changing stat's Value will only show up for you, the change won't show up to anyone else on the server.
That is, unless you use remote events/remote functions
An example of your code with some changes:
local ReplicatedStorage = game:GetService("ReplicatedStorage") local player = game:GetService("Players").LocalPlayer script.Parent.MouseButton1Click:Connect(function() local stats = game.ReplicatedStorage.PlayerMoney:FindFirstChild(player.Name) local tool = game.ReplicatedStorage:FindFirstChild("Copper Sword") --tell the server that you want to buy a copper sword ReplicatedStorage.BuyItem:FireServer("Copper Sword") --[[ DO ALL THIS ON THE SERVER (Script) not client (localscript) local price = 350 if stats.Value >= price then tool:Clone().Parent = plr.Backpack stats.Value = stats.Value - price end ]]-- end)
--This function gets ran whenever the 'BuyItem' event is fired. game.ReplicatedStorage.BuyItem.OnServerEvent:Connect(function(player, item) --THIS IS WHERE YOU'D DO ALL THE CHECKS --TO SEE IF THE PLAYER HAS ENOUGH MONEY -- AND GIVE THE PLAYER THEIR TOOL -- PUT THE CODE I COMMENTED OUT ABOVE HERE. end)
What you need to do for this code to work is create a remote event called BuyItem
and put it in the ReplicatedStorage. You also need to put your PlayerMoney and Copper Sword into the replicated storage too.
didn't explain remote functions in depth so if you need help with that let me know i can explain more in detail if youd like
A GUI Element's MouseButton1Click event does not pass you a reference to the player who clicked it, so your handler function's plr
argument is always going to be nil. You may be confusing this event with ClickDetector.MouseClick which works in server Scripts and does pass you the player who clicked.
Normally, UI is coded all with LocalScripts, where you then know the player is the LocalPlayer. Any input actions the user does that should affect gamestate on the server should be sent to the server using RemoteEvents.