Hey everyone
I’m making an RP themed game, and I really want to make Crates like this where the Crates will get Money and also Tools, but I have a problem where when I open the Crates and get Money… The money doesn’t add to the Leaderstats. so what should I do??
Video
Example of Crates that I want to make
This is the script and Localscript that I used I took this Crates model from Youtube but if you are confused by this code or can’t see the objects from this game you can open my studio file or even watch this Video Crates
LocalScript Code
CratesClient
--Variables
local rs = game:GetService("ReplicatedStorage")
local remotes = rs:WaitForChild("RemoteEvents")
local rarityProperties = rs:WaitForChild("RarityProperties")
local items = rs:WaitForChild("Items")
local crates = rs:WaitForChild("Crates")
local shopGui = script.Parent:WaitForChild("CrateShopGui");shopGui.Enabled = true
local openShopBtn = shopGui:WaitForChild("OpenButton");openShopBtn.Visible = true
local shopFrame = shopGui:WaitForChild("CrateShopFrame");shopFrame.Visible = false
local closeShopBtn = shopFrame:WaitForChild("CloseButton")
local cratesList = shopFrame:WaitForChild("CratesList")
local selectedCrate = shopFrame:WaitForChild("SelectedCrate");selectedCrate.Visible = false
local openedGui = script.Parent:WaitForChild("OpenedCrateGui");openedGui.Enabled = false
local openedFrame = openedGui:WaitForChild("CrateFrame");openedFrame.Visible = false
local closeOpenedBtn = openedFrame:WaitForChild("ContinueButton")
local openedItemsFrame = openedFrame:WaitForChild("ItemsFrame")
local crateButtonTemplate = script:WaitForChild("CrateShopButton")
local selectedCrateItemTemplate = script:WaitForChild("SelectedCrateItemFrame")
local openingCrateItemTemplate = script:WaitForChild("OpeningCrateItemFrame")
local rnd = Random.new()
openShopBtn.MouseButton1Click:Connect(function()
if openedFrame.Visible == false then
shopFrame.Visible = not shopFrame.Visible
end
end)
closeShopBtn.MouseButton1Click:Connect(function()
shopFrame.Visible = false
end)
closeOpenedBtn.MouseButton1Click:Connect(function()
openedFrame.Visible = false
openedGui.Enabled = false
for _, child in pairs(openedItemsFrame.ItemsContainer:GetChildren()) do
if child:IsA("Frame") then
child:Destroy()
end
end
end)
--Setting up crates shop
local crateButtons = {}
for _, crate in pairs(crates:GetChildren()) do
local crateProperties = require(crate)
local newBtn = crateButtonTemplate:Clone()
newBtn.Name = crate.Name
newBtn.CrateName.Text = crate.Name
newBtn.CrateImage.Image = crateProperties["Image"]
newBtn.MouseButton1Click:Connect(function()
if selectedCrate.CrateName.Text ~= crate.Name then
selectedCrate.CrateName.Text = crate.Name
selectedCrate.CrateImage.Image = crateProperties["Image"]
selectedCrate.UnboxButton.Text = "$" .. crateProperties["Price"]
local rarities = {}
for rarityName, chance in pairs(crateProperties["Chances"]) do
table.insert(rarities, {rarityName, chance})
end
table.sort(rarities, function(a, b)
return rarityProperties[a[1]].Order.Value <rarityProperties[b[1]].Order.Value
end)
local raritiesText = ""
for _, rarity in pairs(rarities) do
local color = rarityProperties[rarity[1]].Color.Value
color = {R = math.round(color.R*255); G = math.round(color.G*255); B = math.round(color.B*255)}
raritiesText = raritiesText .. '<font color="rgb(' .. color.R .. ',' .. color.G .. ',' .. color.B .. ')">' .. rarity[1] .. ': <b>' .. rarity[2] .. '%</b></font><br />'
end
selectedCrate.RaritiesText.RichText = true
selectedCrate.RaritiesText.Text = raritiesText
for _, child in pairs(selectedCrate.ItemsList:GetChildren()) do
if child:IsA("Frame") then
child:Destroy()
end
end
local unboxableItems = crateProperties["Items"]
table.sort(unboxableItems, function(a, b)
return
(rarityProperties[items:FindFirstChild(a, true).Parent.Name].Order.Value < rarityProperties[items:FindFirstChild(b, true).Parent.Name].Order.Value)
or (rarityProperties[items:FindFirstChild(a, true).Parent.Name].Order.Value == rarityProperties[items:FindFirstChild(b, true).Parent.Name].Order.Value)
and (a < b)
end)
for _, unboxableItemName in pairs(unboxableItems) do
local newItemFrame = selectedCrateItemTemplate:Clone()
newItemFrame.ItemName.Text = unboxableItemName
newItemFrame.ItemName.TextColor3 = rarityProperties[items:FindFirstChild(unboxableItemName, true).Parent.Name].Color.Value
local itemModel = Instance.new("Model")
for _, child in pairs(items:FindFirstChild(unboxableItemName, true):GetChildren()) do
if not (child:IsA("Script") or child:IsA("LocalScript") or child:IsA("ModuleScript") or child:IsA("Sound")) then
child:Clone().Parent = itemModel
end
end
itemModel:PivotTo(CFrame.new() * CFrame.Angles(math.rad(-39), 0, 0))
itemModel.Parent = newItemFrame.ItemImage
local currentCamera = Instance.new("Camera")
currentCamera.CFrame = CFrame.new(Vector3.new(-itemModel:GetExtentsSize().Y*0.7, 0, 0), itemModel:GetPivot().Position + Vector3.new(0, -0.1, 0))
currentCamera.Parent = newItemFrame.ItemImage
newItemFrame.ItemImage.CurrentCamera = currentCamera
newItemFrame.Parent = selectedCrate.ItemsList
end
selectedCrate.Visible = true
end
end)
table.insert(crateButtons, {newBtn, crateProperties["Price"]})
end
table.sort(crateButtons, function(a, b)
return (a[2] < b[2]) or (a[2] == b[2] and a[1].Name < b[1].Name)
end)
for _, crateButton in pairs(crateButtons) do
crateButton[1].Parent = cratesList
end
--Purchasing crates
selectedCrate.UnboxButton.MouseButton1Click:Connect(function()
if selectedCrate.Visible == true and game.Players.LocalPlayer.leaderstats.Cash.Value >= tonumber(string.sub(selectedCrate.UnboxButton.Text, 2, -1)) then
remotes:WaitForChild("BuyCrate"):FireServer(selectedCrate.CrateName.Text)
end
end)
--Unboxing crates
function lerp(a, b, t)
return a + (b-a) * t
end
function tweenGraph(x, pow)
x = math.clamp(x, 0, 1)
return 1 - (1-x)^pow
end
remotes:WaitForChild("CrateOpened").OnClientEvent:Connect(function(crateName, itemChosen, unboxTime)
local crateProperties = require(crates[crateName])
local numItems = rnd:NextInteger(20, 100)
local chosenPosition = rnd:NextInteger(15, numItems-5)
for i = 1, numItems do
local rarityChosen = itemChosen.Parent.Name
local randomItemChosen = itemChosen
if i ~= chosenPosition then
local rndChance = rnd:NextNumber() * 100
local n = 0
for rarity, chance in pairs(crateProperties["Chances"]) do
n += chance
if rndChance <= n then
rarityChosen = rarity
break
end
end
local unboxableItems = crateProperties["Items"]
for i = #unboxableItems, 2, -1 do
local j = rnd:NextInteger(1, i)
unboxableItems[i], unboxableItems[j] = unboxableItems[j], unboxableItems[i]
end
for _, itemName in pairs(unboxableItems) do
if items:FindFirstChild(itemName, true).Parent.Name == rarityChosen then
randomItemChosen = items:FindFirstChild(itemName, true)
break
end
end
end
local newItemFrame = openingCrateItemTemplate:Clone()
newItemFrame.ItemName.Text = randomItemChosen.Name
newItemFrame.ItemName.TextColor3 = rarityProperties[rarityChosen].Color.Value
local itemModel = Instance.new("Model")
for _, child in pairs(randomItemChosen:GetChildren()) do
if not (child:IsA("Script") or child:IsA("LocalScript") or child:IsA("ModuleScript") or child:IsA("Sound")) then
child:Clone().Parent = itemModel
end
end
itemModel:PivotTo(CFrame.new() * CFrame.Angles(math.rad(-39), 0, 0))
itemModel.Parent = newItemFrame.ItemImage
local currentCamera = Instance.new("Camera")
currentCamera.CFrame = CFrame.new(Vector3.new(-itemModel:GetExtentsSize().Y*0.7, 0, 0), itemModel:GetPivot().Position + Vector3.new(0, -0.1, 0))
currentCamera.Parent = newItemFrame.ItemImage
newItemFrame.ItemImage.CurrentCamera = currentCamera
newItemFrame.Parent = openedItemsFrame.ItemsContainer
end
openedItemsFrame.ItemsContainer.Position = UDim2.new(0, 0, 0.5, 0)
local cellSize = openingCrateItemTemplate.Size.X.Scale
local padding = openedItemsFrame.ItemsContainer.UIListLayout.Padding.Scale
local pos1 = 0.5 - cellSize/2
local nextOffset = -cellSize - padding
local posFinal = pos1 + (chosenPosition-1) * nextOffset
local rndOffset = rnd:NextNumber(-cellSize/2, cellSize/2)
posFinal += rndOffset
local timeOpened = tick()
openedFrame.CrateName.Text = crateName
shopFrame.Visible = false
closeOpenedBtn.Visible = false
openedFrame.Visible = true
openedGui.Enabled = true
local pow = rnd:NextNumber(2, 10)
local lastSlot = 0
while true do
local timeSinceOpened = tick() - timeOpened
local x = timeSinceOpened / unboxTime
local t = tweenGraph(x, pow)
local newXPos = lerp(0, posFinal, t)
local currentSlot = math.abs(math.floor((newXPos+rndOffset)/cellSize))+1
if currentSlot ~= lastSlot then
script.TickSound:Play()
lastSlot = currentSlot
end
openedItemsFrame.ItemsContainer.Position = UDim2.new(newXPos, 0, 0.5, 0)
if x >= 1 then
break
end
game:GetService("RunService").Heartbeat:Wait()
end
closeOpenedBtn.Visible = true
end)
Script Code
CratesServer
local rs = game:GetService("ReplicatedStorage")
local remotes = rs:WaitForChild("RemoteEvents")
local items = rs:WaitForChild("Items")
local crates = rs:WaitForChild("Crates")
local rnd = Random.new()
local playersUnboxing = {}
local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("UNBOXING SYSTEM DATA")
function saveData(plr:Player)
if not plr:FindFirstChild("DATA FAILED TO LOAD") then
local cash = plr.leaderstats.Cash.Value
local inventory = {}
for _, item in pairs(plr.StarterGear:GetChildren()) do
table.insert(inventory, item.Name)
end
if playersUnboxing[plr] then
table.insert(inventory, playersUnboxing[plr])
end
local compiledData = {
Cash = cash;
Inventory = inventory;
}
local success, err = nil, nil
while not success do
success, err = pcall(function()
ds:SetAsync(plr.UserId, compiledData)
end)
if err then
warn(err)
end
task.wait(0.02)
end
end
end
game.Players.PlayerRemoving:Connect(saveData)
game:BindToClose(function()
for _, plr in pairs(game.Players:GetPlayers()) do
saveData(plr)
end
end)
game.Players.PlayerAdded:Connect(function(plr)
local dataFailedWarning = Instance.new("StringValue")
dataFailedWarning.Name = "DATA FAILED TO LOAD"
dataFailedWarning.Parent = plr
local success, plrData = nil, nil
while not success do
success, plrData = pcall(function()
return ds:GetAsync(plr.UserId)
end)
task.wait(0.02)
end
dataFailedWarning:Destroy()
if not plrData then
plrData = {
Cash = 30000;
Inventory = {};
}
end
local ls = Instance.new("Folder")
ls.Name = "leaderstats"
ls.Parent = plr
local cashValue = Instance.new("IntValue")
cashValue.Name = "Cash"
cashValue.Value = plrData.Cash
cashValue.Parent = ls
for _, itemName in pairs(plrData.Inventory) do
local foundItem = items:FindFirstChild(itemName, true)
if foundItem and foundItem.Parent.Parent == items then
foundItem:Clone().Parent = plr:WaitForChild("StarterGear")
if plr.Character then
foundItem:Clone().Parent = plr:WaitForChild("Backpack")
end
end
end
end)
remotes:WaitForChild("BuyCrate").OnServerEvent:Connect(function(plr, crateName)
local plrCash = plr.leaderstats.Cash
if crates:FindFirstChild(crateName) and not playersUnboxing[plr] then
local crateProperties = require(crates[crateName])
if plrCash.Value >= crateProperties["Price"] then
plrCash.Value -= crateProperties["Price"]
local chances = crateProperties["Chances"]
local plrChance = rnd:NextNumber() * 100
local n = 0
local rarityChosen = nil
for rarity, chance in pairs(chances) do
n += chance
if plrChance <= n then
rarityChosen = rarity
break
end
end
local unboxableItems = crateProperties["Items"]
for i = #unboxableItems, 2, -1 do
local j = rnd:NextInteger(1, i)
unboxableItems[i], unboxableItems[j] = unboxableItems[j], unboxableItems[i]
end
local itemChosen = nil
for _, itemName in pairs(unboxableItems) do
if items:FindFirstChild(itemName, true).Parent.Name == rarityChosen then
itemChosen = items:FindFirstChild(itemName, true)
break
end
end
playersUnboxing[plr] = itemChosen.Name
local unboxTime = rnd:NextNumber(3, 7)
remotes:WaitForChild("CrateOpened"):FireClient(plr, crateName, itemChosen, unboxTime)
local timeStarted = tick()
while true do
if (tick() - timeStarted >= unboxTime) or (not plr.Character) then
break
end
game:GetService("RunService").Heartbeat:Wait()
end
playersUnboxing[plr] = nil
itemChosen:Clone().Parent = plr:WaitForChild("StarterGear")
if plr.Character then
itemChosen:Clone().Parent = plr:WaitForChild("Backpack")
end
end
end
end)
Studio File
Crates Studio.rbxl (89.5 KB)