Help with Custom Backpack/Inventory System

I wanted to make a custom inventory which has primary, secondary and tertiary categories, right, which can be accessed with each corresponding button on keyboard.

A functionality i wanted to implement was to cycle through a category while repeatedly pressing the corresponding button, and at the end unequip completely, or cross switch categories.

A problem i encountered was the way i index the items in a table, since i must use GetChildren for it to stay dynamic if a player picks up or removes an item. I use a indexing number to know which item to select when cycling, but the thing is since the items are removed in and out when equipping there have been issues. I’m not sure how to go about this. Would appreciate anybody who had to deal with this sharing some insight. What i have right now:

local equipped_item = nil
local currentindex = 1

user_input_service.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.One then
		local items = backpack_folder:GetChildren()
		
		if not equipped_item then
			
			equip_item(items[currentindex])
			
		elseif equipped_item then
			
			unequip_current()
			
			if #items == currentindex or currentindex> #items then
				currentindex = 1
			else
				currentindex = currentindex+1
				equip_item(items[currentindex])
			end
		end
	end
end)

1 Like

Still havent figured anything out, even though this seems a low-level task

1 Like
local user_input_service = game:GetService("UserInputService")
local backpack_folder = game.Players.LocalPlayer:WaitForChild('XZI')

	local equipped_item = nil
local lastEquippedIndex = 0
local cycleStarted = false

local function equip_item(item)
	-- Equip logic here
	equipped_item = item
	lastEquippedIndex = table.find(backpack_folder:GetChildren(), item)
	print('EQUIPPED:'..' '.. equipped_item.Name)
end

local function unequip_current()
	-- Unequip logic here
	print('UNEQUIPPED:'..' '.. (equipped_item and equipped_item.Name or "nil"))
	equipped_item = nil
end

local function getNextItem()
	local items = backpack_folder:GetChildren()

	if #items == 0 then
		return nil
	end

	if lastEquippedIndex >= #items then
		lastEquippedIndex = 0
		return nil
	end

	lastEquippedIndex = lastEquippedIndex + 1
	return items[lastEquippedIndex]
end

user_input_service.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.One then
		if not cycleStarted and equipped_item then
			unequip_current()
			cycleStarted = true
		end

		local nextItem = getNextItem()

		if nextItem then
			equip_item(nextItem)
		elseif cycleStarted then
			cycleStarted = false
			unequip_current()
		else
			cycleStarted = true
		end
	end
end)

This also just throws errors and doesnt work in general.

1 Like

I don’t think inventory systems are low level tasks. It requires a lot of varied understanding. You need to take it in steps. Why don’t you start with the cycle system:

When a key is pressed, go to corresponding category[1]. For every time the key is pressed again, increase by 1, modulo the total amount of children in the category (so that when you reach the end, you’ll go back to the start).

2 Likes

You are probably right - inventory systems can become a hassle quite quickly…
The thing is i already have that basic logic down, which you mentioned. Its more about caching the items which are parented elsewhere, and implementing some sort of better logic so the index doesnt mess up, which is my biggest problem right now.

I could potentially try static lists or work around my system and have the items stay in the backpack. Ill have to experiment.

2 Likes

Hi,

I managed to figure out the problem, and as I predicted this was indeed a low-level task in camouflage. For anybody wondering, you just need a way to store the array of items while protecting against unequips/equips (Re-parenting).

If anyone wants to make this sort of inventory system, where you can equip, and cycle through the items by pressing the button again, and unequipping at the end, and is unsure how to go about it: here’s a code sample of mine to help you:

local current_actualized_itemindex = {}
local currentindex = 1

backpack_folder.ChildAdded:Connect(function(c) 
	if not table.find(current_actualized_itemindex, c) then
		--print('tool added!')
		table.insert(current_actualized_itemindex, c)
	end
end)

backpack_folder.ChildRemoved:Connect(function(c)
	--print(c)
	if c.Parent ~= view_model then
		--print(c.Parent)
		--print('unadequate parenting, proceeding')

		if table.find(current_actualized_itemindex, c) then
		--	print('tool removed!')
			table.remove(current_actualized_itemindex, table.find(current_actualized_itemindex, c))
		end
	end
end)

local function check_equip()
	if #current_actualized_itemindex == 0 then
		return false
	elseif #current_actualized_itemindex>=1 then
		return true
	end
end

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.