Inventory/Storage System Help

I am wanting to make a very simple and easy storage system (inventory) that I can easy edit latter. I am waning a player to click on the item and a equip ui comes up, player when hits equip and then shows what tool you have equipped.

Ex:

Problem: When I click the item more the twice it does not work
Ex:

I need help fixing this. I have tried almost every thing. I even remade the script piece by piece. It stoped working when I start to clone the item to the MainFrame.

I want it to clone correctly every time even if it it already in MainFrame

The script is a local script located in ScreenGui

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StorageEvent = ReplicatedStorage:WaitForChild("StorageEvent")
local Template = script.Template
local StorageFrame = script.Parent.StorageFrame
local MainFrame = StorageFrame.MainFrame
local InfoFrame = StorageFrame.InfoFrame

local currentSpotIndex = 1

-- CONNECT TO THE CLIENT EVENT FOR STORAGE UPDATES
StorageEvent.OnClientEvent:Connect(function(ItemName, Value)
	if Value then
		-- CREATE OR FIND THE BUTTON FOR THE ITEM
		local ItemButton = MainFrame:FindFirstChild(ItemName) or Template:Clone()
		ItemButton.Name = ItemName

		-- GET THE CURRENT SPOT FOR THE ITEM
		local currentSpot = StorageFrame.SpotFrames["Spot" .. currentSpotIndex]
		ItemButton.Parent = currentSpot
		currentSpotIndex = currentSpotIndex + 1

		-- WRAP AROUND IF INDEX EXCEEDS THE NUMBER OF SPOTFRAMES
		if currentSpotIndex > #StorageFrame.SpotFrames:GetChildren() then
			currentSpotIndex = 1
		end

		-- HANDLE CLICK EVENT ON ITEM BUTTON
		ItemButton.MouseButton1Click:Connect(function()
			local nameTextLabel = InfoFrame.NameTextLabel
			local equipButton = InfoFrame.EquipButton

			-- TOGGLE VISIBILITY OF CLOSE BUTTONS
			StorageFrame.CloseTextButton.Visible = false
			StorageFrame.CloseTextButtonB.Visible = true

			-- SET ITEM NAME IN INFOFRAME
			nameTextLabel.Text = ItemButton.Name
			InfoFrame.Visible = true

			-- HANDLE CLICK EVENT ON EQUIP BUTTON
			equipButton.MouseButton1Click:Connect(function()
				-- DESTROY UISTROKES IN ALL ITEMBUTTONS THAT ARE IN SPOTFRAMES
				local spotFrames = StorageFrame.SpotFrames:GetChildren()

				-- FUNCTION TO CHECK AND DESTROY UISTROKE
				local function checkAndDestroyUIStroke(spotFrame)
					local itemButton = spotFrame:FindFirstChild(ItemName)
					if itemButton and itemButton:IsA("GuiButton") and itemButton:FindFirstChild("UIStroke") then
						itemButton.UIStroke:Destroy()
					end
				end

				-- CHECK AND DESTROY UISTROKE FOR EACH SPOTFRAME
				for _, spotFrame in ipairs(spotFrames) do
					checkAndDestroyUIStroke(spotFrame)
				end

				-- DESTROY EXISTING ITEM BUTTON AND UISTROKE
				local existingItemButton = MainFrame:FindFirstChild(ItemName)
				if existingItemButton then
					local existingUIStroke = existingItemButton:FindFirstChild("UIStroke")
					if existingUIStroke then
						existingUIStroke:Destroy()
					end
					existingItemButton:Destroy()
					return
				end

				-- CREATE NEW UISTROKE, MOVE ITEM TO MAINFRAME, AND HIDE INFOFRAME
				local newUIStroke = script.UIStroke:Clone()
				newUIStroke.Parent = ItemButton
				ItemButton:Clone().Parent = MainFrame
				
				InfoFrame.Visible = false
				StorageFrame.CloseTextButton.Visible = true
				StorageFrame.CloseTextButtonB.Visible = false
			end)
		end)
	end
end)
2 Likes

You need to disconnect the functions or else they will overlap.

Code:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StorageEvent = ReplicatedStorage:WaitForChild("StorageEvent")
local Template = script.Template
local StorageFrame = script.Parent.StorageFrame
local MainFrame = StorageFrame.MainFrame
local InfoFrame = StorageFrame.InfoFrame

local currentSpotIndex = 1

local itemConnection = nil
local equipConnection = nil

-- CONNECT TO THE CLIENT EVENT FOR STORAGE UPDATES
StorageEvent.OnClientEvent:Connect(function(ItemName, Value)
	if not Value then
		return
	end
	
	if itemConnection then
		itemConnection:Disconnect()
		itemConnection = nil
	end
	
	if equipConnection then
		equipConnection:Disconnect()
		equipConnection = nil
	end
	
	-- CREATE OR FIND THE BUTTON FOR THE ITEM
	local ItemButton = MainFrame:FindFirstChild(ItemName) or Template:Clone()
	ItemButton.Name = ItemName

	-- GET THE CURRENT SPOT FOR THE ITEM
	local currentSpot = StorageFrame.SpotFrames["Spot" .. currentSpotIndex]
	ItemButton.Parent = currentSpot
	currentSpotIndex = currentSpotIndex + 1

	-- WRAP AROUND IF INDEX EXCEEDS THE NUMBER OF SPOTFRAMES
	if currentSpotIndex > #StorageFrame.SpotFrames:GetChildren() then
		currentSpotIndex = 1
	end

	-- HANDLE CLICK EVENT ON ITEM BUTTON
	itemConnection = ItemButton.MouseButton1Click:Connect(function()
		if equipConnection then
			equipConnection:Disconnect()
			equipConnection = nil
		end
		
		local nameTextLabel = InfoFrame.NameTextLabel
		local equipButton = InfoFrame.EquipButton

		-- TOGGLE VISIBILITY OF CLOSE BUTTONS
		StorageFrame.CloseTextButton.Visible = false
		StorageFrame.CloseTextButtonB.Visible = true

		-- SET ITEM NAME IN INFOFRAME
		nameTextLabel.Text = ItemButton.Name
		InfoFrame.Visible = true

		-- HANDLE CLICK EVENT ON EQUIP BUTTON
		equipConnection = equipButton.MouseButton1Click:Connect(function()
			-- DESTROY UISTROKES IN ALL ITEMBUTTONS THAT ARE IN SPOTFRAMES
			local spotFrames = StorageFrame.SpotFrames:GetChildren()

			-- FUNCTION TO CHECK AND DESTROY UISTROKE
			local function checkAndDestroyUIStroke(spotFrame)
				local itemButton = spotFrame:FindFirstChild(ItemName)
				if itemButton and itemButton:IsA("GuiButton") and itemButton:FindFirstChild("UIStroke") then
					itemButton.UIStroke:Destroy()
				end
			end

			-- CHECK AND DESTROY UISTROKE FOR EACH SPOTFRAME
			for _, spotFrame in ipairs(spotFrames) do
				checkAndDestroyUIStroke(spotFrame)
			end

			-- DESTROY EXISTING ITEM BUTTON AND UISTROKE
			local existingItemButton = MainFrame:FindFirstChild(ItemName)
			if existingItemButton then
				local existingUIStroke = existingItemButton:FindFirstChild("UIStroke")
				if existingUIStroke then
					existingUIStroke:Destroy()
				end
				existingItemButton:Destroy()
				return
			end

			-- CREATE NEW UISTROKE, MOVE ITEM TO MAINFRAME, AND HIDE INFOFRAME
			local newUIStroke = script.UIStroke:Clone()
			newUIStroke.Parent = ItemButton
			ItemButton:Clone().Parent = MainFrame

			InfoFrame.Visible = false
			StorageFrame.CloseTextButton.Visible = true
			StorageFrame.CloseTextButtonB.Visible = false
		end)
	end)
end)
1 Like

The script only works ish for one item.

1 Like

This works ish. I made it easier to read and made it simpler using local functions

Using Disconnect make it work till I need to equip the item aging

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StorageEvent = ReplicatedStorage:WaitForChild("StorageEvent")
local Template = script.Template
local StorageFrame = script.Parent.StorageFrame
local MainFrame = StorageFrame.MainFrame
local InfoFrame = StorageFrame.InfoFrame

local currentSpotIndex = 1

local function checkAndDestroyUIStroke(spotFrame, ItemName)
	local itemButton = spotFrame:FindFirstChild(ItemName)
	if itemButton and itemButton:IsA("GuiButton") and itemButton:FindFirstChild("UIStroke") then
		itemButton.UIStroke:Destroy()
	end
end

local function onEquipButtonClick(ItemButton, ItemName)
	return function()
		-- DESTROY UISTROKES IN ALL ITEMBUTTONS THAT ARE IN SPOTFRAMES
		local spotFrames = StorageFrame.SpotFrames:GetChildren()

		-- CHECK AND DESTROY UISTROKE FOR EACH SPOTFRAME
		for _, spotFrame in ipairs(spotFrames) do
			checkAndDestroyUIStroke(spotFrame, ItemName)
		end

		-- DESTROY EXISTING ITEM BUTTON AND UISTROKE
		local existingItemButton = MainFrame:FindFirstChild(ItemName)
		if existingItemButton then
			local existingUIStroke = existingItemButton:FindFirstChild("UIStroke")
			if existingUIStroke then
				existingUIStroke:Destroy()
			end
			existingItemButton:Destroy()
			return
		end

		-- CREATE NEW UISTROKE, MOVE ITEM TO MAINFRAME, AND HIDE INFOFRAME
		local newUIStroke = script.UIStroke:Clone()
		newUIStroke.Parent = ItemButton
		ItemButton:Clone().Parent = MainFrame

		InfoFrame.Visible = false
		StorageFrame.CloseTextButton.Visible = true
		StorageFrame.CloseTextButtonB.Visible = false
	end
end

-- CONNECT TO THE CLIENT EVENT FOR STORAGE UPDATES
StorageEvent.OnClientEvent:Connect(function(ItemName, Value)
	if Value then
		-- CREATE OR FIND THE BUTTON FOR THE ITEM
		local ItemButton = MainFrame:FindFirstChild(ItemName) or Template:Clone()
		ItemButton.Name = ItemName

		-- GET THE CURRENT SPOT FOR THE ITEM
		local currentSpot = StorageFrame.SpotFrames["Spot" .. currentSpotIndex]
		ItemButton.Parent = currentSpot
		currentSpotIndex = currentSpotIndex + 1

		-- WRAP AROUND IF INDEX EXCEEDS THE NUMBER OF SPOTFRAMES
		if currentSpotIndex > #StorageFrame.SpotFrames:GetChildren() then
			currentSpotIndex = 1
		end

		-- HANDLE CLICK EVENT ON ITEM BUTTON
		local clickConnection
		clickConnection = ItemButton.MouseButton1Click:Connect(function()
			local nameTextLabel = InfoFrame.NameTextLabel
			local equipButton = InfoFrame.EquipButton

			-- TOGGLE VISIBILITY OF CLOSE BUTTONS
			StorageFrame.CloseTextButton.Visible = false
			StorageFrame.CloseTextButtonB.Visible = true

			-- SET ITEM NAME IN INFOFRAME
			nameTextLabel.Text = ItemButton.Name
			InfoFrame.Visible = true

			-- HANDLE CLICK EVENT ON EQUIP BUTTON
			equipButton.MouseButton1Click:Connect(onEquipButtonClick(ItemButton, ItemName))

			-- Disconnect the ItemButton click event once it's no longer needed
			clickConnection:Disconnect()
		end)
	end
end)