Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How do I fix the swapping function for my Inventory system?

I've been working on an inventory system for a survival game I've been working on, and I've been having trouble with it. I've been lately working specifically on the swapping function, where you can select an item, press a button, and then if you press 1 for example, the selected item will go in slot 1 of the hotbar. However, when I programmed the code for the swapping to actually happen, it didn't work. I believe it was due to the updateDisplay function and how it works, since the item's data was still in the hotbar slot.

Code is below (go to lines 116 and 188 ):

local StarterGui = game:GetService("StarterGui")
local Players = game:GetService("Players")
local UIS = game:GetService("UserInputService")

StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)

local player = Players.LocalPlayer
local backpack = player.Backpack
local char = player.Character

local GUI = script.Parent.Parent.Inventory
local hotbar = GUI.Hotbar
local inventory = GUI.Inventory
local items = inventory.Items

local tooltip = inventory.Tooltip
local itemNameT = inventory.Tooltip.ToolName
local itemDescription = inventory.Tooltip.Tooltip

local slot1 = inventory.Items.InventorySlot1
local slot2 = inventory.Items.InventorySlot2
local slot3 = hotbar.Frame.HotbarSlot1
local slot4 = hotbar.Frame.HotbarSlot2
local openButton = hotbar.OpenInventory
local equipButton = inventory.EquipHotbarButton

local unselctedColor = Color3.fromRGB(121, 121, 121)
local selectedColor = Color3.fromRGB(62, 62, 62)

local selectedSlot = nil


local invSlotData = {
	[slot1] = nil,
	[slot2] = nil	
}

local hotbarSlotData = {
	[slot3] = nil,
	[slot4] = nil
}

local function scanItems()

	local items = {}

	--checks backpack and character for items and adds them to the Items table
	for i, tool in pairs(backpack:GetChildren()) do
		if tool.ClassName == "Tool" then
			table.insert(items, tool)
		end
	end

	for i, tool in pairs(char:GetChildren()) do
		if tool.ClassName == "Tool" then
			table.insert(items, tool)
		end
	end


	local invItems = {}

	--[[looks through Items table, and if a tool has the same name as an index in invItems table, add to the index's count and insert
	the tool's name into the index's Items table. else, create a new index with the tool's name and set all it's tables to default  --]]
	for i, tool in pairs(items) do
		if invItems[tool.Name] then
			invItems[tool.Name].Count += 1
			table.insert(invItems[tool.Name].Items, tool)
			
		else
			invItems[tool.Name] = {
				Count = 1,
				Items = {tool}
			}
		end
	end

	return invItems
end

local function resetItems()
	for i, button in pairs(items:GetChildren()) do
		if button.ClassName == "ImageButton" then
			button.Image = ""
			button.CountDisplay.Text = ""
			button.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
		end
	end
	
	for i, button in pairs(hotbar.Frame:GetChildren()) do
		if button.ClassName == "ImageButton" then
			button.Image = ""
			button.CountDisplay.Text = ""
			button.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
		end
	end
end

local function updateSelected(selectedItem, toolData)
	--checks all buttons in items frame and resets all background colors to default except sample


	--[[  selectedItem's background color is changed to selectedColor and selectedSlot is set to toolData.
	selectedItem's name and tooltip is pulled from toolData and used for tooltip in inventory.--]]
	selectedSlot = toolData


	itemNameT.Text = toolData.Items[1].Name
	itemDescription.Text = toolData.Items[1].ToolTip
end


--UPDATE DISPLAY FUNCTION IS HERE, CHECK THIS OUT IF YOURE FIXING SCRIPT


local function updateDisplay()
	resetItems()

	local invItems = scanItems()
	local connection = nil
	local equipButtonConnection = nil


	for toolName, toolData in pairs(invItems) do
		if invSlotData[slot1] == nil or toolData.Items[1].Name == invSlotData[slot1].Items[1].Name then

			invSlotData[slot1] = toolData

			slot1.CountDisplay.Text = toolData.Count
			slot1.Image = toolData.Items[1].TextureId



			connection = slot1.MouseButton1Click:Connect(function()
				updateSelected(slot1, toolData)
			end)

		elseif invSlotData[slot2] == nil or toolData.Items[1].Name == invSlotData[slot2].Items[1].Name then


			invSlotData[slot2] = toolData

			slot2.CountDisplay.Text = toolData.Count
			slot2.Image = toolData.Items[1].TextureId



			connection = slot2.MouseButton1Click:Connect(function()
				updateSelected(slot2, toolData)
			end)

		elseif hotbarSlotData[slot3] == nil or toolData.Items[1].Name == hotbarSlotData[slot3].Items[1].Name then


			hotbarSlotData[slot3] = toolData

			slot3.CountDisplay.Text = toolData.Count
			slot3.Image = toolData.Items[1].TextureId



			connection = slot3.MouseButton1Click:Connect(function()
				updateSelected(slot3, toolData)
			end)


		elseif hotbarSlotData[slot4] == nil or toolData.Items[1].Name == hotbarSlotData[slot4].Items[1].Name then

			hotbarSlotData[slot4] = toolData

			slot4.CountDisplay.Text = toolData.Count
			slot4.Image = toolData.Items[1].TextureId


			connection = slot4.MouseButton1Click:Connect(function()
				updateSelected(slot4, toolData)
			end)

		end

	end

end

--SWAPPING ITEMS FUNCTION IS ALSO HERE


local equipButtonDebounce = false

local keysToSlots = {
	[Enum.KeyCode.One] = slot3,
	[Enum.KeyCode.Two] = slot4,
}

local function swapItemSlots()

	if selectedSlot == nil or equipButtonDebounce == true then
		equipButton.Text = "Can't Equip to Hotbar"
		wait(1)
		equipButton.Text = "Equip to Hotbar"

		return
	end

	equipButtonDebounce = true

	equipButton.Text = "Press a Number 1-2"

	local input, gameProcessedEvent = UIS.InputBegan:Wait()

	equipButton.Text = "Equip to Hotbar"



	local chosenHotbarSlot = nil

	for keycode, slot in pairs(keysToSlots) do
		if input.KeyCode == keycode then
			chosenHotbarSlot = slot
			break
		end
	end

	if chosenHotbarSlot == nil then
		equipButton.Text = "Wrong Button!"

		task.wait(1)

		equipButton.Text = "Equip to Hotbar"
	else
		for slotF, itemData in pairs(hotbarSlotData) do
			if itemData.Items[1].Name == selectedSlot.Items[1].Name then
				hotbarSlotData[slotF] = nil
				print(hotbarSlotData)
			end

		end
		
		hotbarSlotData[chosenHotbarSlot] = selectedSlot
		selectedSlot = nil
		updateDisplay()
		
		
        print(chosenHotbarSlot)
		print(invSlotData)
		print(hotbarSlotData)
	end

    equipButtonDebounce = false

end

equipButton.MouseButton1Click:Connect(swapItemSlots)




task.spawn(function()
	while true do
		wait(1)
		updateDisplay()
	end
end)

1 answer

You're using equipButton.MouseButton1Click:Connect(swapItemSlots)

That will only call the function if the player clicks. If you use game:GetService("UserInputService").InputBegan:Connect(swapItemSlots) it should work because it will be called when any kind of input is passed by the player.

This discussion is preserved as it was. New answers, comments, and votes are closed.