Hey everyone!
I’ve been scripting a custom inventory system in which the items are string values where the name of the value is the name of the item and the value is a UUID string created with GenerateGUID.
These values are inside of a folder parented to the player, and the inventory script loops through that folder and creates a button for each of those items.
For the equipping and unequipping part I have some GUI “slots” and when a button is clicked it gets parented to one of those slots and a remote event is fired so the actual welding of the weapon and armor models can happen.
So far so good! Until I encountered a problem, what if I need to delete one of those items? So, to handle that I created another frame with an equip/unequip button and a delete one, changed my script so that the remote event was fired when the equip/unequip button is pressed and not the item one and it works, but I have created some sort of bug where, the first time that I equip/unequip something it behaves as it should, but afterwards it looks like the buttons “think” they are all the same one and start equipping/unequipping everything that was already in the slots.
I’m sure I’m overlooking an if statement I should be making or something I should be adding somewhere, but I’m in need of some outside input on the logic I created here.
robloxapp-20220407-1253126.wmv (560.1 KB)
The Inventory Local Script
local EquipWeaponRemote = game.ReplicatedStorage:WaitForChild("GameRemotes"):WaitForChild("EquipWeapon")
local EquipArmorRemote = game.ReplicatedStorage:WaitForChild("GameRemotes"):WaitForChild("EquipArmor")
local InHandRemote = game.ReplicatedStorage:WaitForChild("GameRemotes"):WaitForChild("InHand")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UnequipWeaponRemote = ReplicatedStorage:WaitForChild("GameRemotes"):WaitForChild("UnequipWeapon")
local UnequipArmorRemote = ReplicatedStorage:WaitForChild("GameRemotes"):WaitForChild("UnequipArmor")
local weapons = ReplicatedStorage:WaitForChild("ItemsInfo"):WaitForChild("WeaponInfo")
local player = game.Players.LocalPlayer
local character = player.Character
local playerInventory = player:WaitForChild("Inventory")
local equippedItems = player:WaitForChild("Info")
local equippedWeapon = equippedItems:WaitForChild("Weapon")
local equippedArmor = equippedItems:WaitForChild("Armor")
local inHandBool = player:WaitForChild("Bools"):WaitForChild("InHand")
local aftersenditem = ReplicatedStorage:WaitForChild("GameRemotes"):WaitForChild("AfterSendItem")
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack,false)
local items = {}
local buttons = {}
function searchInventory()
for i,v in pairs(playerInventory:GetChildren()) do
if v:isA("StringValue") then
table.insert(items,v)
end
end
end
function searchEquipped()
for i,v in pairs(equippedItems:GetChildren()) do
if v:isA("StringValue") then
end
end
end
function addInventoryBtn (item)
local itemType = ReplicatedStorage.ItemsInfo.WeaponInfo[item.Name].ItemType.Value
local itemHover = script.Parent.Parent.ItemHover
local button = script.SlotTemplate:Clone()
local listitem = {item.Name, item.Value}
button.LayoutOrder = 1
button.Name = item.Name
button.Value.Value = item.Name .. "::" .. item.Value
button.Image = "rbxassetid://"..ReplicatedStorage.ItemsInfo.WeaponInfo[item.Name].ItemPicture.Value
button.Parent = script.Parent.ScrollingFrame
table.insert(buttons, button)
button.MouseButton1Click:Connect(function()
if itemHover.Visible == false then
itemHover.Visible = true
itemHover.NameText.Text = item.Name
if itemType == "Weapon" then
itemHover.Stats.Text = "Damage:" .. ReplicatedStorage.ItemsInfo.WeaponInfo[item.Name].Damage.Value
if button.Value.Value == equippedWeapon.Value then
itemHover.EquipBtn.Text = "Unequip"
itemHover.EquipBtn.MouseButton1Click:Connect(function()
if itemHover.EquipBtn.Text == "Unequip" and button.Value.Value == equippedWeapon.Value then
UnequipWeaponRemote:FireServer(listitem)
itemHover.Visible = false
end
end)
elseif button.Value.Value ~= equippedWeapon.Value then
itemHover.EquipBtn.Text = "Equip"
itemHover.EquipBtn.MouseButton1Click:Connect(function()
if itemHover.EquipBtn.Text == "Equip" and equippedWeapon.Value == "" then
EquipWeaponRemote:FireServer(listitem)
itemHover.Visible = false
end
end)
end
elseif itemType == "Armor" then
itemHover.Stats.Text = "Health: " .. ReplicatedStorage.ItemsInfo.WeaponInfo[item.Name].HP.Value .."\nDefense:" .. ReplicatedStorage.ItemsInfo.WeaponInfo[item.Name].Defense.Value
if button.Value.Value == equippedArmor.Value then
itemHover.EquipBtn.Text = "Unequip"
itemHover.EquipBtn.MouseButton1Click:Connect(function()
if itemHover.EquipBtn.Text == "Unequip" and button.Value.Value == equippedArmor.Value then
UnequipArmorRemote:FireServer(listitem)
itemHover.Visible = false
end
end)
elseif button.Value.Value ~= equippedArmor.Value then
itemHover.EquipBtn.Text = "Equip"
itemHover.EquipBtn.MouseButton1Click:Connect(function()
if itemHover.EquipBtn.Text == "Equip" and equippedArmor.Value == "" then
EquipArmorRemote:FireServer(listitem)
itemHover.Visible = false
end
end)
end
end
else
itemHover.Visible = false
end
end)
end
function createInventory ()
local playerInventoryLoaded = playerInventory:GetChildren()
for i = 1, #playerInventoryLoaded do
addInventoryBtn(playerInventoryLoaded[i])
handleWeaponEquip()
handleArmorEquip()
end
end
function handleWeaponEquip ()
print("handleEquip", equippedWeapon.Value)
if equippedWeapon.Value == "" then
local weaponBtn = script.Parent.Parent.Char.Weapon
if weaponBtn.Value.Value == "" then
return
end
weaponBtn.Name = weaponBtn.Value.Value
weaponBtn.Parent = script.Parent.ScrollingFrame
weaponBtn = script.Parent.Parent.Char.placeholderWeapon
weaponBtn.Name = "Weapon"
else
local weaponBtn = script.Parent.Parent.Char.Weapon
for i,btn in pairs(script.Parent.ScrollingFrame:GetChildren()) do
if btn:IsA("UIGridLayout") then
continue
end
if btn.Value.Value == equippedWeapon.Value then
btn.Parent = script.Parent.Parent.Char
btn.Name = weaponBtn.Name
btn.Position = weaponBtn.Position
btn.Size = weaponBtn.Size
weaponBtn.Name = "placeholderWeapon"
end
end
end
end
function handleArmorEquip ()
print("handleEquip", equippedArmor.Value)
if equippedArmor.Value == "" then
local armorBtn = script.Parent.Parent.Char.Armor
if armorBtn.Value.Value == "" then
return
end
armorBtn.Name = armorBtn.Value.Value
armorBtn.Parent = script.Parent.ScrollingFrame
armorBtn = script.Parent.Parent.Char.placeholderArmor
armorBtn.Name = "Armor"
else
local armorBtn = script.Parent.Parent.Char.Armor
for i,btn in pairs(script.Parent.ScrollingFrame:GetChildren()) do
if btn:IsA("UIGridLayout") then
continue
end
if btn.Value.Value == equippedArmor.Value then
btn.Parent = script.Parent.Parent.Char
btn.Name = armorBtn.Name
btn.Position = armorBtn.Position
btn.Size = armorBtn.Size
armorBtn.Name = "placeholderArmor"
end
end
end
end
function handleAdd (child)
addInventoryBtn(child)
end
function backpackRefresh()
items = {}
searchInventory()
end
items = {}
searchInventory()
createInventory()
equippedWeapon.Changed:Connect(handleWeaponEquip)
equippedArmor.Changed:Connect(handleArmorEquip)
aftersenditem.OnClientEvent:Connect(handleAdd)
player.Inventory.ChildAdded:connect(handleAdd)
player.Inventory.ChildRemoved:connect(backpackRefresh)
character.ChildAdded:connect(backpackRefresh)
character.ChildRemoved:connect(backpackRefresh)
The part in the Server Script that handles the equipping remotes
EquipWeaponRemote.OnServerEvent:Connect(function(Player, weapon_item)
local info = Player:WaitForChild("Info")
AddWeapon(Player, weapon_item)
end)
UnequipWeaponRemote.OnServerEvent:Connect(function(player, weapon_item)
local info = player:WaitForChild("Info")
info.Weapon.Value = ""
player.Character:WaitForChild("Weapon"):Destroy()
end)
EquipArmorRemote.OnServerEvent:Connect(function(Player, armor_item)
local info = Player:WaitForChild("Info")
local playerStats = Player:WaitForChild("PlayerStats")
local defense = playerStats:WaitForChild("Defense")
local HP = playerStats:WaitForChild("Health")
local itemDefense = ReplicatedStorage.ItemsInfo.WeaponInfo[armor_item[1]].Defense
local itemHP = ReplicatedStorage.ItemsInfo.WeaponInfo[armor_item[1]].HP
local character = Player.Character
local humanoid = character.Humanoid
info.Armor.Value = armor_item[1] .."::".. armor_item[2]
HP.Value += itemHP.Value
humanoid.MaxHealth = HP.Value
defense.Value += itemDefense.Value
end)
UnequipArmorRemote.OnServerEvent:Connect(function(Player, armor_item)
local info = Player:WaitForChild("Info")
local playerStats = Player:WaitForChild("PlayerStats")
local defense = playerStats:WaitForChild("Defense")
local HP = playerStats:WaitForChild("Health")
local itemDefense = ReplicatedStorage.ItemsInfo.WeaponInfo[armor_item[1]].Defense
local itemHP = ReplicatedStorage.ItemsInfo.WeaponInfo[armor_item[1]].HP
local character = Player.Character
local humanoid = character.Humanoid
info.Armor.Value = ""
defense.Value -= itemDefense.Value
HP.Value -= itemHP.Value
humanoid.MaxHealth = HP.Value
humanoid.Health = HP.Value
end)
I’m sorry for the long post and thank you for your time!