I have a button that fires a remote event and when its fired a server script checks if the player has enough money for the car they want to buy. I want to make it so that if they don’t have enough money, the text on the button changes to say that but I don’t know how to do that with a server script
My code:
game.ReplicatedStorage.DealershipEvents.BuyCar.OnServerEvent:Connect(function(player,Car)
local Price = game.ServerStorage.ShopCars:FindFirstChild(Car).Price.Value
local Coins = player.leaderstats.Coins
if Price and Coins.Value >= Price and player.OwnedCars:FindFirstChild(Car).Value == false then
Coins.Value = Coins.Value - Price
player.OwnedCars:FindFirstChild(Car).Value = true
end
end)
Either you can change the text from server accessing players PlayerGui, or you can send the client a remote event so the player will locally change the text. It’s always better to force client change UI things instead of doing it on server, but it’s possible. Players → PlayerName → PlayerGui → …
Important thing to remember is even if server can change player’s UI, there are some limits, for example listeners, you’re unable to add on click listener to the button from the server side. Server can change UI only visibly.
This is server’s view on Player, there you can see his PlayerGui
I tried using a remote event and having it fire when there wasn’t enofuh coins and the button was clicked and then having it show that on the client but it didn’t work
script.Parent.MouseButton1Click:Connect(function()
local result = game.ReplicatedStorage.DealershipEvents:WaitForChild('BuyCar'):InvokeServer(player, Car)
if result == "Sufficient" then
-- if works change gui text and etc
else
--code that says you're extremely poor, try again.
end
end
Server Script:
game.ReplicatedStorage.DealershipEvents:WaitForChild("BuyCar").OnServerInvoke = function(player, car, price) -- change as needed
if player.leaderstats.Coins >= price then
-- code to remove coins from player and give car
return("Sufficient")
else
return("Insufficient Funds")
end
end
I can try that but i need to see how to fix the problem where if you don’t have enough money for the car but click the button, the next time you join it’ll say you own the car
If you want me to ill give you the data saving code part
It doesnt really check if you don’t have the money but checks if you do have it
game.ReplicatedStorage.DealershipEvents.BuyCar.OnServerEvent:Connect(function(player,Car)
local Price = game.ServerStorage.ShopCars:FindFirstChild(Car).Price.Value
local Coins = player.leaderstats.Coins
if Price and Coins.Value >= Price and player.OwnedCars:FindFirstChild(Car).Value == false then
Coins.Value = Coins.Value - Price
player.OwnedCars:FindFirstChild(Car).Value = true
end
end)
Yes, you can use RemoteFunction and return a value.
What you could do is, that after successful buy, you’re gonna return true boolean, if unsuccessful, you’re gonna return a value indicating this error. By this conversation I assume, you’re not very into programming at this time, so you can return a string value with the error message.
game.ReplicatedStorage.DealershipEvents.BuyCar.OnServerInvoke = function(player,Car)
local Price = game.ServerStorage.ShopCars:FindFirstChild(Car).Price.Value
local Coins = player.leaderstats.Coins
if Price and Coins.Value >= Price and player.OwnedCars:FindFirstChild(Car).Value == false then
Coins.Value = Coins.Value - Price
player.OwnedCars:FindFirstChild(Car).Value = true
return true
end
return "Insufficient Funds"
end
This solution is not very secure. On your server script, I see that you’re accepting price parameter, which is wrong. You never ask a client about the price, since any exploiter could just modify this piece of code, and always provide a price of 1 or 0.
Price must be always defined server-side.
Another wrong practice is checking value by string, which is on client script. Easier and well deterministic solution would be, that server would return an integer indicating the status of purchase. 1 => success, 0 => Insufficient Funds.
In my previous response, I suggested using boolean | string type, where string would be returned only in cases where purchase was unsuccessful.
After purchase, you can directly change the button text on player’s UI in the server-script
You can use RemoteFunction and return an integer or boolean stating the result of purchase ((1/true) => Success, (0/false) => Failure)
You can use RemoteFunction and return true if purchase was success or a string if failure.
I’d recommend using the second option in all use-cases, because this is the most optimal way how to it, since you just send one integer over network, sending as less data as possible is always better.
Server Script:
game.ReplicatedStorage.DealershipEvents.BuyCar.OnServerInvoke = function(player,Car)
local Price = game.ServerStorage.ShopCars:FindFirstChild(Car).Price.Value
local Coins = player.leaderstats.Coins
if Price and Coins.Value >= Price and player.OwnedCars:FindFirstChild(Car).Value == false then
Coins.Value = Coins.Value - Price
player.OwnedCars:FindFirstChild(Car).Value = true
return true
end
return false
end
Client Script:
local button = ...
button.Activated:Connect(function()
local result = game.ReplicatedStorage.DealershipEvents.BuyCar:InvokeServer(Car)
if result then return end -- We don't need to do anything else if payment was success
button.Text = "No Funds!"
task.spawn(function() -- Creates new thread
task.wait(5) -- Waits 5 seconds
button.Text = "Buy" -- After 5 seconds, set the button text back to its default value
end)
end)
I made this my button code and it doesn’t work but I feel like I did something wrong should I have the second part of the code in the first part
script.Parent.MouseButton1Down:Connect(function()
local player = game.Players.LocalPlayer
local Car = script.Parent.Parent.Car.Value
if player and script.Parent.Parent.Selected.Value == true then
game.ReplicatedStorage.DealershipEvents.BuyCar:FireServer(Car)
if player.OwnedCars:FindFirstChild(Car).Value == true then
script.Parent.Text = "Car already owned!"
wait(2)
script.Parent.Text = "Purchase car"
end
end
end)
local button = script.Parent
button.Activated:Connect(function()
local Car = script.Parent.Parent.Car.Value
local result = game.ReplicatedStorage.DealershipEvents.BuyCar.InvokeServer(Car)
if result then return end -- We don't need to do anything else if payment was success
button.Text = "Not enough coins!"
task.spawn(function() -- Creates new thread
task.wait(2) -- Waits 2 seconds
button.Text = "Purchase car" -- After 2 seconds, set the button text back to its default value
end)
end)