I am trying to make an unboxing system that looks like this. I got the gui and made scripts to do make it happen. I used this to make the system.
The problem is the system I use images for the rewards. I am wanting the reward to be a tool.
I can do this by changing the script so it clones a tool from the CloneTools folder, but I don’t know how to change it in the script. I spent hours on it and I can finger it out.
This script is a LOCAL SCRIPT LOCATED IN THE GUI
-- << SERVICES >>
-- Get necessary services
local players = game:GetService("Players")
local rs = game:GetService("ReplicatedStorage")
local contentProvider = game:GetService("ContentProvider")
local tweenService = game:GetService("TweenService")
local runService = game:GetService("RunService")
-- << VARIABLES >>
-- Define variables for various game elements
local player = players.LocalPlayer
local gui = player.PlayerGui.SpinnerGUIs
local spinner = gui.Spinner
local spinnerMain = spinner.Main
local spinnerReward = spinner.Reward
local claim = spinnerReward.Claim
local spin1 = spinnerReward.Spin1
local spin2 = spinnerReward.Spin2
local crates = spinnerMain.Crates
local holder = crates.Holder
local template = crates.Template
local templateX = template.AbsoluteSize.X
local crateGapX = 10
local crateTotalGapX = templateX + crateGapX
local line = spinnerMain.Line
local skip = spinnerMain.Skip
local activate = gui.ActivateSpinner
local spin = activate.Spin
local contentsModule = rs:WaitForChild("SpinnerContents")
local contents = require(contentsModule)
local itemTypes = contents:GetItemTypes()
local rfunction = contentsModule.RemoteFunction
local spinDe = true
local assetsToLoad = {}
local skipped = false
local skipTime = 0.5
local direction
local rewardSound = script.RewardSound
-- << LOCAL FUNCTIONS >>
-- Define a function to display or hide the spinner GUI
local function DisplaySpinner(bool)
local oppositeBool = true
if bool then
oppositeBool = false
end
spinner.Visible = bool
activate.Visible = oppositeBool
end
-- << SETUP >>
-- Set up crates, skip button, claim button, preloading items, and hide display
template.Visible = true
for i = 1, contents.Crates do
local pos = i-1
local crate = template:Clone()
crate.Name = "Crate"..i
if string.lower(string.sub(contents.SpinDirection,1,1)) == "r" then
direction = "Right"
crate.Position = crate.Position + UDim2.new(0, crateTotalGapX*pos, 0, 0)
else
direction = "Left"
crate.Position = crate.Position + UDim2.new(1, -(templateX+10)-(crateTotalGapX*pos), 0, 0)
end
crate.Parent = holder
end
template.Visible = false
-- Skip button event
skip.MouseButton1Down:Connect(function()
skipped = true
end)
-- Claim button event
claim.MouseButton1Down:Connect(function()
DisplaySpinner(false)
end)
-- Preload items
coroutine.wrap(function()
for rarityPos, group in pairs(itemTypes) do
for i, item in pairs(group.Items) do
local decal = Instance.new("Decal")
decal.Texture = "rbxassetid://"..item.ImageId
table.insert(assetsToLoad, decal)
end
end
contentProvider:PreloadAsync(assetsToLoad)
for i,v in pairs(assetsToLoad) do
if v:IsA("Decal") then
v:Destroy()
end
end
end)()
-- Hide display
DisplaySpinner(false)
-- << MAIN >>
-- Define the main spinning function
function SpinFunction(spinDetails)
-- Variables
local items = spinDetails.Items
local winningCrateId = spinDetails.WinningCrateId
local winningItem = spinDetails.WinningItem
local duplicate = spinDetails.Duplicate
local cratesRemaining = {}
skipped = false
-- Setup crates
holder.Position = UDim2.new(0,0,0,0)
for i, item in pairs(items) do
local crate = holder["Crate"..i]
local rarityGroup = itemTypes[item.GroupIndex].Rarity
crate.About.ItemName.Text = item.Name
crate.About.ItemRarity.Text = rarityGroup.Name
crate.ImageLabel.Image = "rbxassetid://"..item.ImageId
crate.About.BackgroundColor3 = rarityGroup.Color
if i <= winningCrateId+1 then
table.insert(cratesRemaining, crate)
end
end
-- Calculate distance to travel
local endCrate = holder["Crate"..winningCrateId]
local startX = crates.AbsolutePosition.X + crates.AbsoluteSize.X/2
local endX = endCrate.AbsolutePosition.X + endCrate.AbsoluteSize.X/2
local xDifference = endX - startX
local yDifference = endCrate.AbsolutePosition.Y - holder.AbsolutePosition.Y
local templateXBound = templateX/2.5
local randomDepth = 1000
local landOffset = 0--math.random(-templateXBound+randomDepth, templateXBound+randomDepth)-randomDepth
local landPosition = holder.Position - UDim2.new(0, xDifference, 0, 0) --startCrate.Position - endCrate.Position
-- Setup tween
local tweenTime = math.random(contents.SpinTimeBounds[1], contents.SpinTimeBounds[2])
local tweenInfo = TweenInfo.new(tweenTime, contents.SpinEasingStyle, contents.SpinEasingDirection)
local tween = tweenService:Create(holder, tweenInfo, {Position = landPosition})
-- Setup tween
local tweenTime = math.random(7,8)
local tweenInfo = TweenInfo.new(tweenTime, contents.SpinEasingStyle, contents.SpinEasingDirection)
local tween = tweenService:Create(holder, tweenInfo, {Position = landPosition})
-- SpinClick sounds
local lineX = line.AbsolutePosition.X
coroutine.wrap(function()
repeat runService.RenderStepped:Wait()
local cratesRemainingInt = #cratesRemaining
local nextCrate = cratesRemaining[1]
if nextCrate then
local nextCrateX = nextCrate.AbsolutePosition.X
if (direction == "Right" and nextCrateX <= lineX) or (direction == "Left" and nextCrateX >= lineX) then
table.remove(cratesRemaining, 1)
local sound = nextCrate.SpinClick
sound:Play()
end
end
until cratesRemainingInt <= 1 or skipped
if skipped then
local newTweenInfo = TweenInfo.new(skipTime, contents.SpinEasingStyle)
local newTween = tweenService:Create(holder, newTweenInfo, {Position = landPosition})
newTween:Play()
newTween.Completed:Wait()
end
skip.Visible = false
end)()
-- Show spinner
spinnerMain.Visible = true
spinnerReward.Visible = false
skip.Visible = true
DisplaySpinner(true)
-- Run tween
tween:Play()
tween.Completed:Wait()
skip.Visible = false
if skipped then
wait(skipTime+0.25)
end
-- Display reward
local winningItem = items[winningCrateId]
local rewardColor
local rarityGroup = itemTypes[winningItem.GroupIndex].Rarity
if duplicate then
local h,s,v = Color3:ToHSV(rarityGroup.Color)
rewardColor = Color3.fromHSV(h, s*0.4, v*0.8)
spinnerReward.Title.Text = contents.Messages.RewardDuplicate1(rarityGroup.Name)
spinnerReward.ItemName.Text = contents.Messages.RewardDuplicate2(rarityGroup.DuplicateReward)
else
rewardColor = rarityGroup.Color
spinnerReward.Title.Text = contents.Messages.RewardNewItem
spinnerReward.ItemName.Text = winningItem.Name
end
spin1.ImageColor3 = rewardColor
spin2.ImageColor3 = rewardColor
spinnerReward.ItemImage.Image = "rbxassetid://"..winningItem.ImageId
spinnerReward.Visible = true
spinnerMain.Visible = false
coroutine.wrap(function()
local rotationTime = 1
local rotationInfo = TweenInfo.new(rotationTime, Enum.EasingStyle.Linear)
while spinnerReward.Visible do
tweenService:Create(spin1, rotationInfo, {Rotation = spin1.Rotation + 30}):Play()
tweenService:Create(spin2, rotationInfo, {Rotation = spin2.Rotation - 60}):Play()
wait(rotationTime)
end
end)()
rewardSound:Play()
end
-- Select Spin
spin.MouseButton1Down:Connect(function()
if spinDe then
spinDe = false
local originalSpinText = spin.TextLabel.Text
if not contents:PermissionToSpin(player) then
spin.TextLabel.Text = contents.Messages.FailPermissionCheck
wait(1)
else
spin.TextLabel.Text = contents.Messages.Loading
local spinDetails, errorMessage = rfunction:InvokeServer()
if not spinDetails then
if not errorMessage then
errorMessage = contents.Messages.ServerError
end
spin.TextLabel.Text = errorMessage
wait(1)
else
SpinFunction(spinDetails)
end
end
spin.TextLabel.Text = originalSpinText
spinDe = true
end
end)
This script is a SERVER SCRIPT LOCATED IN SERVERSCRIPTSERVICE
-- << SERVICES >>
local rs = game:GetService("ReplicatedStorage")
-- << VARIABLES >>
local contentsModule = rs:WaitForChild("SpinnerContents")
local contents = require(contentsModule)
local rfunction = contentsModule.RemoteFunction
local chanceDepth = 100000000
local itemTypes = contents:GetItemTypes()
-- << MAIN >>
function rfunction.OnServerInvoke(player)
if not contents:PermissionToSpin(player) then
return false
else
-- Eliminate already-owned items
local modifiedItemTypes = contents:GetItemTypes()
if contents.EliminateOwnedItems then
-- Get table of currently owned items
local ownedItems = {}
for i, v in pairs(player.leaderstats.Inventory:GetChildren()) do
ownedItems[v.Name] = true
end
-- Iterate through each group
for groupIndex, group in pairs(modifiedItemTypes) do
local totalItems = #group.Items
local totalItemsPlusOne = totalItems + 1
-- Iterate through Items back-to-front so the items remain in the same position if one is removed
for i = 1, totalItems do
local itemIndex = totalItemsPlusOne - i
local item = group.Items[itemIndex]
if ownedItems[item.Name] then
table.remove(group.Items, itemIndex)
end
end
end
end
-- Generate Items
local items = {}
for i = 1, contents.Crates do
-- Determine rarity
local cumulativeChance = 0
local rarityGroup
local randomChance = math.random(1, chanceDepth) / chanceDepth
for groupIndex, group in pairs(modifiedItemTypes) do
local chance = group.Rarity.Chance
cumulativeChance = cumulativeChance + chance
if randomChance <= cumulativeChance and #group.Items > 0 then
rarityGroup = group
break
end
end
-- If user has collected all items, return error message
if not rarityGroup then
return nil, contents.Messages.ServerErrorComplete
end
-- Select random item from rarity group and add to 'items' table
local newItemsGroup = rarityGroup.Items
local newItemPos = math.random(1, #newItemsGroup)
local newItem = newItemsGroup[newItemPos]
table.insert(items, newItem)
end
-- Deduct price
local leaderstats = player.leaderstats
local stat = leaderstats.Cash
stat.Value = stat.Value - contents.Price
-- Generate Crate Details and Winning Item
local winningCrateId = contents.Crates - 5
local winningItem = items[winningCrateId]
-- Check if duplicate, if not, reward item
local duplicate = false
if contents.DuplicateReward and leaderstats.Inventory:FindFirstChild(winningItem.Name) then
duplicate = true
leaderstats.Cash.Value = leaderstats.Cash.Value + itemTypes[winningItem.GroupIndex].Rarity.DuplicateReward
else
leaderstats.Items.Value = leaderstats.Items.Value + 1
local newStat = Instance.new("ObjectValue")
newStat.Name = winningItem.Name
newStat.Parent = leaderstats.Inventory
end
-- Returns spin details
return {
["Items"] = items;
["WinningCrateId"] = winningCrateId;
["WinningItem"] = winningItem;
["Duplicate"] = duplicate;
}
end
end
This script is a MODAL SCRIPT LOCATED IN REPLICATEDSTORAGE
-- Table to store configuration and data
local contents = {}
-- Configuration settings
contents["Price"] = 100; -- Price to spin the wheel
contents["Crates"] = 45; -- Number of crates
contents["SpinTimeBounds"] = {7,8} -- Bounds for spinning time
contents["SpinEasingStyle"] = Enum.EasingStyle.Quart; -- Easing style for spinning animation
contents["SpinEasingDirection"] = Enum.EasingDirection.Out; -- Easing direction for spinning animation
contents["SpinDirection"] = "Right"; -- Direction for spinning animation
contents["DuplicateReward"] = true; -- Set to true to receive the 'DuplicateReward' for already-owned items. Set to false to receive the item again.
contents["EliminateOwnedItems"] = true; -- Set to true to remove already-owned items from the spinner.
-- Messages to display during different events
contents["Messages"] = {
Loading = "Loading...";
FailPermissionCheck = "Not enough cash!";
ServerError = "Error!";
ServerErrorComplete = "Error: unlocked all possible items!";
RewardNewItem = "New Item!";
RewardDuplicate1 = function(a) return("Duplicate "..a.."!") end; -- where 'a' is the RarityName
RewardDuplicate2 = function(a) return("+"..a.." Cash") end; -- where 'a' is the DuplicateCashReward
}
-- Permission check function
function contents:PermissionToSpin(player)
local leaderstats, cash = player:FindFirstChild("leaderstats")
if leaderstats then
cash = leaderstats:FindFirstChild("Cash")
end
if cash and cash.Value >= contents.Price then
return true
else
return false
end
end
-- Function to get item types and rarities
function contents:GetItemTypes()
local itemTypes = {
-- Common items
{
Rarity = {Name = "Common", Chance = 0.589, Color = Color3.fromRGB(0,85,127), DuplicateReward = 20};
Items = {
{Name = "Item1", ImageId = 2419083546};
{Name = "Item2", ImageId = 1468821126};
{Name = "Item3", ImageId = 2643944686};
{Name = "Item4", ImageId = 1468821305};
{Name = "Item5", ImageId = 1468822149};
}
};
-- Uncommon items
{
Rarity = {Name = "Uncommon", Chance = 0.300, Color = Color3.fromRGB(43,125,43), DuplicateReward = 50};
Items = {
{Name = "Item6", ImageId = 1468821620};
{Name = "Item7", ImageId = 1801056307};
{Name = "Item8", ImageId = 2419083419};
{Name = "Item9", ImageId = 1468820879};
{Name = "Item10", ImageId = 2643944712};
}
};
-- Rare items
{
Rarity = {Name = "Rare", Chance = 0.100, Color = Color3.fromRGB(210,85,0), DuplicateReward = 100};
Items = {
{Name = "Item11", ImageId = 1471365373};
{Name = "Item12", ImageId = 1468818998};
{Name = "Item13", ImageId = 1468820407};
{Name = "Item14", ImageId = 2570569323};
{Name = "Item15", ImageId = 1468820383};
}
};
-- Legendary items
{
Rarity = {Name = "Legendary", Chance = 0.010, Color = Color3.fromRGB(170,0,0), DuplicateReward = 200};
Items = {
{Name = "Item16", ImageId = 2419084522};
{Name = "Item17", ImageId = 1468819804};
{Name = "Item18", ImageId = 2419083272};
{Name = "Item19", ImageId = 1468820065};
{Name = "Item20", ImageId = 1468821559};
}
};
-- Mythical items
{
Rarity = {Name = "Mythical", Chance = 0.001, Color = Color3.fromRGB(170,0,225), DuplicateReward = 500};
Items = {
{Name = "Item21", ImageId = 2987584671};
}
};
};
-- Records the group the item belongs to. This can be used to retrieve data on the item's group (such as its rarity, color, etc) when we only have info for the item.
for groupIndex, group in pairs(itemTypes) do
for i, item in pairs(group.Items) do
item.GroupIndex = groupIndex
end
end
return itemTypes
end
-- Return the contents table
return contents
How do I change these scripts to give me a tool instead of a image