Hello! I made a simple system like the title says, and figured id share!
This tutorial goes very quickly over how to add a money leaderstat (without datastorers!), and then the cash dropping system.
Sections:
- UI
- Leaderstat setup
- Cash dropping system
- Cash picking up system
First up because it is arguable the simplest, the UI!
Im going to be using a very simple rectangle for UI with a button and text label for amount and activation, but feel free to customize!
The only things the ui needs to have is a textbox to select how much cash the player wishes to drop, and some form of button to tell the code that they want to drop the selected amount of cash
As the main client script were going to drop this [LocalScript] under the screenGUI but it could be under plrScripts or characterScripts or anything like that
local plr = game.Players.LocalPlayer
local ui = script.Parent
local frame = ui.MainFrame
local dropBtn = frame.DropCash
local amount = frame.CashAmount
-- obviously assign to your own frame, btn, and textbox if you made a custom gui
local currentMoney = plr.leaderstats.Money
local remote = game.ReplicatedStorage.DropMoney
dropBtn.Activated:Connect(function()
local am = amount.Text
if tonumber(am) then -- basic check to see if the text is a number
am = tonumber(am)
remote:FireServer(am)
end
end)
then moving swiftly on to making the leaderstats (skip this part if you already have your money leaderstat setup)
server script under ServerScriptService, this is the script we will be using for the majority of the rest of the code
game.Players.PlayerAdded:Connect(function(plr)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = plr -- folder under the player, tells roblox to display the leaderstats in the gui leaderboard
local m = Instance.new("IntValue")
m.Name = "Money"
m.Value = 250
m.Parent = leaderstats -- money int, im starting them off with 250 so I can test the dropping system, but feel free to start with any amount of your choice!
end)
pick up here if you skipped the leaderstat part!
then were going to want to add some variables, above the function we just pasted in
local repStorage = game:GetService("ReplicatedStorage")
local remote = repStorage.DropMoney
local cashObject = repStorage.CashObject
-- remote event, as well as the block we are going to drop to display as a cash object
local BaseCashObjectWorth = 75 -- used for v1, the max amount per 1 cash
local CashDropTimes = 5 -- used for v2, the max amount of pieces of cash we could drop
local v = true
-- true = v1, false = v2 - youll understand later in the tutorial
we could make the cashpart through the code like Instance.new("Part")
but I found it easier to make it in rep storage
and while making this part, remember to add a remoteevent to replicatedStorage and name it “DropMoney” if youre copying my code, otherwise rename it and change the variable in the code
now remember to put that part in ReplicatedStorage
Under that cashpart, add a number value “Amount”, this will tell the pickup code how much cash this object is holding, also under the cashpart, not the amount value, the part itself, a proximityprompt, and a script under the prompt
Is there 100% a better way to detect the prompt input, yes
Am I going to remember it or do it? no
what repStorage should look like currently:
then going back into that main script, were going to add a function for later, right above the leaderstats creating function
local function dropCash(cashWorth : number, pos : Vector3, plrMoneyObject : IntValue)
plrMoneyObject.Value -= cashWorth -- take the cash that the plr is dropping
local clone = cashObject:Clone()
clone.Parent = workspace -- clone the cash object
clone.Amount.Value = cashWorth
clone.Position = pos -- put the cash near the player character
end
and finally we can make the main section of the money dropping code
We want to detect on the remoteEvent fire from the client when the btn is hit, and the code comments should explain the rest.
remote.OnServerEvent:Connect(function(plr, dropAmount : number)
if not tonumber(dropAmount) then return end -- check to make sure its a number
local money = plr.leaderstats.Money -- the players money object
end)
adding onto that, checking if we have all of the money
remote.OnServerEvent:Connect(function(plr, dropAmount : number)
if not tonumber(dropAmount) then return end -- check to make sure its a number
local money = plr.leaderstats.Money -- the players money object
if money.Value >= dropAmount then -- if we have enough money
end
end)
now taking a big step here, remember to read the comments! (inside of the money.Value check)
local function v1()
-- continues dropping cash until weve dropped all the cash requested, so in theory you could drop upwards of 1000+ pieces of cash, would reccomend adding something that if the amount is < X then do v1 else do v2
local dropTimes = dropAmount / BaseCashObjectWorth
for i = dropTimes, 0, -1 do
if i > 1 then -- if its not a decimal, whole number
dropCash(BaseCashObjectWorth, plr.Character.HumanoidRootPart.Position, money)
dropAmount -= BaseCashObjectWorth
else -- if it is a decimal, not a whole number
dropCash(dropAmount, plr.Character.HumanoidRootPart.Position, money)
break
end
end
end
local function v2()
-- arguably the better system, would recommend using this one!1!!11111!111!11!1
-- it drops 5 pieces of cash, and then distriputes the amount to drop among them
local amPerCash = dropAmount / CashDropTimes
for i = CashDropTimes, 0, -1 do
dropCash(amPerCash , plr.Character.HumanoidRootPart.Position, money)
end
end
-- just whichever one is selected with the bool at the top of the script
if v then
v1()
else
v2()
end
final script:
local repStorage = game:GetService("ReplicatedStorage")
local remote = repStorage.DropMoney
local cashObject = repStorage.CashObject
-- remote event, as well as the block we are going to drop to display as a cash object
local BaseCashObjectWorth = 75 -- used for v1, the max amount per 1 cash
local CashDropTimes = 5 -- used for v2, the max amount of pieces of cash we could drop
local v = true
-- true = v1, false = v2
local function dropCash(cashWorth : number, pos : Vector3, plrMoneyObject : IntValue)
plrMoneyObject.Value -= cashWorth -- take the cash that the plr is dropping
local clone = cashObject:Clone()
clone.Parent = workspace -- clone the cash object
clone.Amount.Value = cashWorth
clone.Position = pos -- put the cash near the player character
end
game.Players.PlayerAdded:Connect(function(plr)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = plr -- folder under the player, tells roblox to display the leaderstats in the gui leaderboard
local m = Instance.new("IntValue")
m.Name = "Money"
m.Value = 250
m.Parent = leaderstats -- money int, im starting them off with 250 so I can test the dropping system, but feel free to start with any amount of your choice!
end)
remote.OnServerEvent:Connect(function(plr, dropAmount : number)
if not tonumber(dropAmount) then return end -- check to make sure its a number
local money = plr.leaderstats.Money -- the players money object
if money.Value >= dropAmount then -- if we have enough money
local function v1()
-- continues dropping cash until weve dropped all the cash requested, so in theory you could drop upwards of 1000+ pieces of cash, would reccomend adding something that if the amount is < X then do v1 else do v2
local dropTimes = dropAmount / BaseCashObjectWorth
for i = dropTimes, 0, -1 do
if i > 1 then -- if its not a decimal, whole number
dropCash(BaseCashObjectWorth, plr.Character.HumanoidRootPart.Position, money)
dropAmount -= BaseCashObjectWorth
else -- if it is a decimal, not a whole number
dropCash(dropAmount, plr.Character.HumanoidRootPart.Position, money)
break
end
end
end
local function v2()
-- arguably the better system, would recommend using this one!1!!11111!111!11!1
-- it drops 5 pieces of cash, and then distriputes the amount to drop among them
local amPerCash = dropAmount / CashDropTimes
for i = CashDropTimes, 0, -1 do
dropCash(amPerCash , plr.Character.HumanoidRootPart.Position, money)
end
end
-- just whichever one is selected with the bool at the top of the script
if v then
v1()
else
v2()
end
end
end)
And for the very last part, the pickup system!
Remember that script we put under the prompt under the cash object under- you get the idea
Inside of that we need to do some stuff
local cash = script.Parent.Parent
local prompt = cash.ProximityPrompt
local amount = cash.Amount
prompt.Triggered:Connect(function(plr) -- .Triggered is fired when the prompt is finished, so if you add a wait it will run when the whole prompt has been filled
local money = plr.leaderstats.Money
money.Value += amount -- give them the cash
cash:Destroy() -- destroy the cash object
end)
and there it is!
please comment any code errors you find, or spelling errors, spelling isnt my strong suit; as well as any exploits or bugs, ill respond as soon as I can!
cashDropTutorial.rbxl (48.6 KB)