-
What do you want to achieve? Keep it simple and clear!
I don’t really know to explain this, because it seems a bit complicated but i’ll try
my best. Basically, I’m trying to create an inventory where you can equip multiple
items. -
What is the issue? Include screenshots / videos if possible!
The issue is that a) items keep duplicating, b)you can only change one item,
and the other item would not be able to change, which means there is no way to
unequip it even if it’s equipped. -
What solutions have you tried so far? Did you look for solutions on the
Developer Hub? Yes I’ve looked through solutions on the developer hub, but there
is nothing even related to this.Basically I’m making a inventory system, or shop system, where you are able to
buy items and you can equip and unequip them. The problem is that if you try to
equip and unequip more then one item, it literally doesn’t work. You end up having
duplicate items. There are two mini viewports that show your item that is
equipped, and they both show the same item. This shouldn’t be happening
because you can’t have multiples of one item, but rather different items. Since it
shows 2 of the same item, when you unequip that item it works. That item e.g gun
gets unequipped from the viewport, but you still have it in the other viewport.
Additionally, even though you already unequipped it, if you go over to shop and
view the item, it say equip, this means that it thinks that the item is
unequipped. It is unequipped, but since this item is duplicated it shows on the
other viewport.I know this seems very confusing but you might be able to understand after
looking at the vid. Also soz for the bad quality, I recorded this on roblox studio.robloxapp-20200725-2153182.wmv (1.1 MB)
Some screenshots:
This is a script in Starter Gui - kinda big
Script
-- -- Core UI localscript
local availableTools = game.ReplicatedStorage:WaitForChild("GetTools"):InvokeServer()
local mainFrame = script.Parent.Frame:WaitForChild("MainFrame")
local safeArea = mainFrame:WaitForChild("SafeArea")
local itemInformation = safeArea:WaitForChild("ItemInformation")
local infoFrame = itemInformation.InfoFrame
local selectedItem = itemInformation.SelectedItem
local selectedItem2 = itemInformation.SelectedItem2
local equippedItem = itemInformation.EquippedItem
local equippedItem2 = itemInformation.EquippedItem2
local numberOfItems = #availableTools
local backgroundframestats= mainFrame.StatsFrame.BackgroundFrameStats
local viewport2 = mainFrame.StatsFrame.BackgroundFrameStats.ViewportFrame2
local frame = script.Parent.Frame
local AttackStats = frame.MainFrame.StatsFrame.BackgroundFrameStats.ViewportFrame2.Attack
local EfficiencyStats = frame.MainFrame.StatsFrame.BackgroundFrameStats.ViewportFrame2.Efficiency
local FireRateStats = frame.MainFrame.StatsFrame.BackgroundFrameStats.ViewportFrame2.Firerate
local CapacityStats = frame.MainFrame.StatsFrame.BackgroundFrameStats.ViewportFrame2.Capacity
local infoViewport = frame.MainFrame.StatsFrame
local Info = infoFrame.ScrollingFrame.MoreInfo
local description = infoFrame.ScrollingFrame.Description
local itemFrame = safeArea.ItemFrame
local shopButton = script.Parent:WaitForChild("ShopButton")
local buyButton = infoFrame.BuyButton
local equippedItemViewport = script.Parent:WaitForChild("EquippedItemViewport")
local itemViewport = itemInformation.ItemViewport
local equippedItemViewport2 = script.Parent:WaitForChild("EquippedItemViewport2")
game.ReplicatedStorage.SendEquipped.OnClientEvent:Connect(function(equipped)
equippedItem.Value = equipped
if equippedItem.Value ~= "" then
local fakeCam = Instance.new("Camera")
fakeCam.Parent = equippedItemViewport
local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(equippedItem.Value.."Handle"):Clone()
handle.Parent = equippedItemViewport
equippedItemViewport.CurrentCamera = fakeCam
fakeCam.CFrame = handle.CameraCFrame.Value
end
end)
game.ReplicatedStorage.SendEquipped2.OnClientEvent:Connect(function(equipped2)
equippedItem2.Value = equipped2
if equippedItem2.Value ~= "" then
local fakeCam2 = Instance.new("Camera")
fakeCam2.Parent = equippedItemViewport
local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(equippedItem2.Value.."Handle"):Clone()
handle.Parent = equippedItemViewport2
equippedItemViewport2.CurrentCamera = fakeCam2
fakeCam2.CFrame = handle.CameraCFrame.Value
end
end)
Info.MouseButton1Click:Connect(function()
infoViewport.Visible = not infoViewport.Visible
end)
shopButton.MouseButton1Click:Connect(function()
frame.Visible = not frame.Visible
end)
local PADDING_X = 0
local DROPDOWN_Y = 0.2
local DROPDOWN_X = 0.25
local item1 = itemFrame:WaitForChild("Item1")
local box
local numRows = 1
for i = 1,numberOfItems,1 do
if i == 1 then
box = item1
else
box = item1:Clone()
box.Name = "Item"..i
box.Parent = itemFrame
if (i-1) / (4*numRows) == 1 then
-- New row
numRows = numRows + 1
box.Position = UDim2.new(PADDING_X,0,box.Position.Y.Scale,0) + UDim2.new(0,0,DROPDOWN_Y*(numRows - 1))
else
-- Add to the X only
box.Position = itemFrame["Item"..(i-1)].Position + UDim2.new(DROPDOWN_X,0,0,0)
end
end
box.MouseButton1Click:Connect(function()
for _, v in pairs(itemViewport:GetChildren())do
if not v:IsA("Frame") then
v:Destroy()
end
end
local itemViewportCam = Instance.new("Camera")
itemViewportCam.Parent = itemViewport
local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(availableTools[i][1].."Handle"):Clone()
handle.Parent = itemViewport
itemViewport.CurrentCamera = itemViewportCam
itemViewportCam.CFrame = handle.CameraCFrame.Value
local owned = game.ReplicatedStorage.ItemCheck:InvokeServer(availableTools[i][1])
if equippedItem.Value == availableTools[i][1] then
infoFrame.Cash.Text = "Owned"
infoFrame.BuyButton.Text = "Unequip"
elseif owned == true then
infoFrame.Cash.Text = "Owned"
infoFrame.BuyButton.Text = "Equip"
else
infoFrame.BuyButton.Text = "Buy"
infoFrame.Cash.Text = "$"..availableTools[i][2]
end
infoFrame.ItemName.Text = availableTools[i][1]
selectedItem.Value = availableTools[i][1]
infoFrame.ScrollingFrame.Description.Text = availableTools[i][3]
infoFrame.ScrollingFrame.MoreInfo.Text = availableTools[i][4]
AttackStats.Text = "Attack: ".. availableTools[i][5]
EfficiencyStats.Text = "Efficiency: ".. availableTools[i][6]
FireRateStats.Text = "Fire rate: ".. availableTools[i][7]
CapacityStats.Text = "Capacity: " .. availableTools[i][8]
-- See Stats Camera -- For Each Weapon -- Mouse Rotation
local InfoViewportCam = Instance.new("Camera")
InfoViewportCam.Parent = viewport2
local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(availableTools[i][1].."Handle"):Clone()
handle.Parent = viewport2
viewport2.CurrentCamera = InfoViewportCam
InfoViewportCam.CFrame = handle.CameraCFrame.Value
for _, v in pairs(itemFrame:GetChildren()) do
if v:IsA("ImageButton") then
v.BorderSizePixel = 0
end
end
itemFrame["Item"..i].BorderSizePixel = 2
end)
local fakeCam = Instance.new("Camera")
fakeCam.Parent = box.VPF
local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(availableTools[i][1].."Handle"):Clone()
handle.Parent = box.VPF
box.VPF.CurrentCamera = fakeCam
fakeCam.CFrame = handle.CameraCFrame.Value
itemFrame["Item"..i].ItemName.Text = availableTools[i][1]
-- Generating Boxes))
end
buyButton.MouseButton1Click:Connect(function()
local result = game.ReplicatedStorage.PurchaseItem:InvokeServer(selectedItem.Value)
if result == true then
buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
buyButton.Text = "Bought!"
wait(0.5)
buyButton.Text = "Equip!"
buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
elseif result == "NotEnoughCash" then
buyButton.BackgroundColor3 = Color3.fromRGB(204,31,31)
buyButton.Text = "Not enough cash!"
wait(0.5)
buyButton.Text = "Buy"
buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
elseif result == "Equipped" then
equippedItem.Value = selectedItem.Value
buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
buyButton.Text = "Equipped!"
wait(0.5)
buyButton.Text = "Unequip"
buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
elseif result == "Unequipped" then
equippedItem.Value = ""
buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
buyButton.Text = "Unequipped"
wait(0.5)
buyButton.Text = "Equip"
buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
end
end)
buyButton.MouseButton1Click:Connect(function()
local result2 = game.ReplicatedStorage.PurchaseItem2:InvokeServer(selectedItem2.Value)
if result2 == true then
buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
buyButton.Text = "Bought!"
wait(0.5)
buyButton.Text = "Equip!"
buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
elseif result2 == "NotEnoughCash" then
buyButton.BackgroundColor3 = Color3.fromRGB(204,31,31)
buyButton.Text = "Not enough cash!"
wait(0.5)
buyButton.Text = "Buy"
buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
elseif result2 == "Equipped" then
equippedItem2.Value = selectedItem2.Value
buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
buyButton.Text = "Equipped!"
wait(0.5)
buyButton.Text = "Unequip"
buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
elseif result2 == "Unequipped" then
equippedItem2.Value = ""
buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
buyButton.Text = "Unequipped"
wait(0.5)
buyButton.Text = "Equip"
buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
end
end)
if equippedItem.Value ~= "" then
local fakeCam = Instance.new("Camera")
fakeCam.Parent = equippedItemViewport
local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(equippedItem.Value.."Handle"):Clone()
handle.Parent = equippedItemViewport
equippedItemViewport.CurrentCamera = fakeCam
fakeCam.CFrame = handle.CameraCFrame.Value
end
if equippedItem2.Value ~= "" then
local fakeCam2 = Instance.new("Camera")
fakeCam2.Parent = equippedItemViewport2
local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(equippedItem2.Value.."Handle"):Clone()
handle.Parent = equippedItemViewport2
equippedItemViewport2.CurrentCamera = fakeCam2
fakeCam2.CFrame = handle.CameraCFrame.Value
end
equippedItem:GetPropertyChangedSignal("Value"):Connect(function()
if equippedItem.Value ~= "" then
for _, v in pairs(equippedItemViewport:GetChildren()) do
if not v:IsA("Folder") then
v:Destroy()
end
end
local fakeCam = Instance.new("Camera")
fakeCam.Parent = equippedItemViewport
local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(equippedItem.Value.."Handle"):Clone()
handle.Parent = equippedItemViewport
equippedItemViewport.CurrentCamera = fakeCam
fakeCam.CFrame = handle.CameraCFrame.Value
else
for _, v in pairs(equippedItemViewport:GetChildren()) do
if not v:IsA("Folder") then
v:Destroy()
end
end
end
end)
equippedItem2:GetPropertyChangedSignal("Value"):Connect(function()
if equippedItem2.Value ~= "" then
for _, v in pairs(equippedItemViewport2:GetChildren()) do
if not v:IsA("Folder") then
v:Destroy()
end
end
local fakeCam2 = Instance.new("Camera")
fakeCam2.Parent = equippedItemViewport2
local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(equippedItem2.Value.."Handle"):Clone()
handle.Parent = equippedItemViewport2
equippedItemViewport2.CurrentCamera = fakeCam2
fakeCam2.CFrame = handle.CameraCFrame.Value
else
for _, v in pairs(equippedItemViewport2:GetChildren()) do
if not v:IsA("Folder") then
v:Destroy()
end
end
end
end)
This is a server script responsible for getting the items
Script
game.ReplicatedStorage:WaitForChild("GetTools").OnServerInvoke = function(player)
local items = {}
for _, object in pairs(game.ServerStorage:WaitForChild("Items"):GetChildren()) do
local itemProperties = {object.Name,object.Price.Value, object.Description.Value, object.Info.Value, object.Attack.Value, object.Efficiency.Value, object.FireRate.Value,object.Capacity.Value}
table.insert(items,itemProperties)
end
return items
end
game.ReplicatedStorage:WaitForChild("ItemCheck").OnServerInvoke = function(player,itemName)
if game.ServerStorage.PlayerData:FindFirstChild(player.Name).Inventory:FindFirstChild(itemName) then
return true
else
return false
end
end
game.ReplicatedStorage:WaitForChild("PurchaseItem").OnServerInvoke = function(player,itemName)
local coins = player.leaderstats.Coins
local gems = player.leaderstats.Gems
local item = game.ServerStorage.Items:FindFirstChild(itemName)
if item then
-- Item exists
if game.ServerStorage.PlayerData[player.Name].Inventory:FindFirstChild(itemName) then
if game.ServerStorage.PlayerData[player.Name].Equipped.Value ~= itemName then
-- Currently unequipped
game.ServerStorage.PlayerData[player.Name].Equipped.Value = itemName
return "Equipped"
else
game.ServerStorage.PlayerData[player.Name].Equipped.Value = ""
return "Unequipped"
end
end
end
game.ReplicatedStorage:WaitForChild("PurchaseItem2").OnServerInvoke = function(player,itemName)
local coins = player.leaderstats.Coins
local gems = player.leaderstats.Gems
local item = game.ServerStorage.Items:FindFirstChild(itemName)
if item then
-- Item exists
if game.ServerStorage.PlayerData[player.Name].Inventory:FindFirstChild(itemName) then
if game.ServerStorage.PlayerData[player.Name].Equipped2.Value ~= itemName then
-- Currently unequipped
game.ServerStorage.PlayerData[player.Name].Equipped2.Value = itemName
return "Equipped"
else
game.ServerStorage.PlayerData[player.Name].Equipped2.Value = ""
return "Unequipped"
end
end
if coins.Value >= item.Price.Value then
coins.Value = coins.Value - item.Price.Value
local itemValue = Instance.new("ObjectValue")
itemValue.Name = itemName
itemValue.Parent = game.ServerStorage.PlayerData[player.Name].Inventory
return true
else
return "NotEnoughCash"
end
else
return "NoItem"
end
end
end
This is another server script responsible for datastores and saving
Script
local dataStores = game:GetService("DataStoreService"):GetDataStore("CoinsDataStore")
local defaultCash = 10
local playersLeft = 0
local defaultGems = 10
game.Players.PlayerAdded:Connect(function(player)
playersLeft = playersLeft + 1
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Value = 0
coins.Parent = leaderstats
local gems = Instance.new("IntValue")
gems.Name = "Gems"
gems.Value = 0
gems.Parent = leaderstats
local playerData = Instance.new("Folder")
playerData.Name = player.Name
playerData.Parent = game.ServerStorage.PlayerData
local equipped = Instance.new("StringValue")
equipped.Name = "Equipped"
equipped.Parent = playerData
local equipped2 = Instance.new("StringValue")
equipped2.Name = "Equipped2"
equipped2.Parent = playerData
local inventory = Instance.new("Folder")
inventory.Name = "Inventory"
inventory.Parent = playerData
player.CharacterAdded:Connect(function(character)
character.Humanoid.Died:Connect(function()
-- Whenever somebody dies, this event will run
if character.Humanoid and character.Humanoid:FindFirstChild("creator") then
game.ReplicatedStorage.Status.Value = tostring(character.Humanoid.creator.Value).." KILLED "..player.Name
end
if character:FindFirstChild("GameTag") then
character.GameTag:Destroy()
end
player:LoadCharacter()
end)
end)
--Data Stores
local gems_data
local player_data
local weaponsData
local equippedData
local equippedData2
pcall(function()
gems_data = dataStores:GetAsync(player.UserId.."Gems") -- 13454546 Gems
end)
pcall(function()
player_data = dataStores:GetAsync(player.UserId.."-Coins") -- 1736284 Coins
end)
pcall(function()
weaponsData = dataStores:GetAsync(player.UserId.."-Weps") -- Weapons Data
end)
pcall(function()
equippedData = dataStores:GetAsync(player.UserId.."-EquippedValue") -- Equipped Weapon Data
end)
pcall(function()
equippedData2 = dataStores:GetAsync(player.UserId.."-EquippedValue2") -- Equipped2 Weapon Data
end)
if player_data ~= nil then
-- Player has saved data, load it in
coins.Value = player_data
else
-- New player
coins.Value = defaultCash
end
if gems_data ~= nil then
-- Player has saved data, load it in
gems.Value = gems_data
else
-- New player
gems.Value = defaultGems
end
if weaponsData then
-- {"Sword3","Sword2","Sword","Icegun")
for _, weapon in pairs(weaponsData) do
if game.ServerStorage.Items:FindFirstChild(weapon) then
local weaponClone = game.ServerStorage.Items[weapon]:Clone()
weaponClone.Parent = inventory
print(weapon.." loaded in!")
end
end
if equippedData then
equipped.Value = equippedData
player:WaitForChild("PlayerGui")
game.ReplicatedStorage.SendEquipped:FireClient(player,equippedData)
end
if equippedData2 then
equipped2.Value = equippedData2
player:WaitForChild("PlayerGui")
game.ReplicatedStorage.SendEquipped2:FireClient(player,equippedData2)
end
else
print("No weapons data")
end
end)
local bindableEvent = Instance.new("BindableEvent")
game.Players.PlayerRemoving:Connect(function(player)
pcall(function()
dataStores:SetAsync(player.UserId.."-Coins",player.leaderstats.Coins.Value)
print("Saved")
end)
pcall(function()
dataStores:SetAsync(player.UserId.."Gems",player.leaderstats.Gems.Value)
print("Saves")
end)
pcall(function()
local weapons = game.ServerStorage.PlayerData[player.Name].Inventory:GetChildren()
local weaponsTable = {}
for _, v in pairs(weapons) do
table.insert(weaponsTable,v.Name)
end
dataStores:SetAsync(player.UserId.."-Weps",weaponsTable)
if game.ServerStorage.PlayerData[player.Name].Equipped.Value ~= nil then
local equippedVal = game.ServerStorage.PlayerData[player.Name].Equipped
dataStores:SetAsync(player.UserId.."-EquippedValue",equippedVal.Value)
if game.ServerStorage.PlayerData[player.Name].Equipped2.Value ~= nil then
local equippedVal2 = game.ServerStorage.PlayerData[player.Name].Equipped2
dataStores:SetAsync(player.UserId.."-EquippedValue2",equippedVal2.Value)
end
end
end)
print("Saved weapons and points")
playersLeft = playersLeft - 1
bindableEvent:Fire()
end)
game:BindToClose(function()
-- This will be triggered upon shutdown
while playersLeft > 0 do
bindableEvent.Event:Wait()
end
end)
-- Data Saving (((((())))))
Any help would be really appreciated, thanks. I’m not much a good scripter, but i spent hours facing this obstacle, and am pretty exhausted.