(SOLVED) Stacking Hotbar

I want to add on to my simple hotbar script using stacking any help would be appreciated. Im sending 500 robux if anyone can help me with this. This is what i got so far
Screenshot 2023-09-26 at 8.11.48 PM
Screenshot 2023-09-26 at 8.12.10 PM

-- [ SETTINGS ] --

local backgroundColor = Color3.fromRGB(0, 132, 255) -- The color of each circle
local maxOnHotbar = 10 -- How many tools can be displayed. Setting this to more than 10 reverts to 10

-- [ END SETTINGS ] --

-- Don't edit if you don't know what you're doing --

local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local p = Players.LocalPlayer
local Backpack = p.Backpack
local Character = p.Character
local Frame = script.Parent.Frame
local Template = Frame.Contents.objTemplate

local COLOR_DARKER = 0.65
local KEY_DICTIONARY = { Zero = 10, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9 }
local EQUIP_TWEENINFO = TweenInfo.new(0.25, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
local items = {}
local tweens = {}


local function handleEquip(tool)
	if tool.Parent ~= Character then
		Character.Humanoid:EquipTool(tool)
	else
		Character.Humanoid:UnequipTools()
	end
end


local function checkHotbar(removeIndex)
	if removeIndex then
		for _, toolCircle in pairs(Frame.Contents:GetChildren()) do
			if toolCircle:IsA("GuiObject") then
				if tonumber(toolCircle.Name) >= removeIndex then
					local newIndex = (tonumber(toolCircle.Name) == 11) and 0 or tonumber(toolCircle.Name) - 1
					local isVisible = (maxOnHotbar == 10) and (newIndex <= 9 and true or false) or ((newIndex ~= 0 and newIndex <= maxOnHotbar) and true or false)

					toolCircle.LayoutOrder -= 1
					toolCircle.Name -= 1
					toolCircle.Visible = isVisible
					toolCircle.Index.Text = newIndex
				end
			end
		end
	end

	local additionalIndex = Frame.AdditionalIndex
	additionalIndex.Size = UDim2.new(0, Frame.Contents.UIListLayout.AbsoluteContentSize.X + Frame.Contents.AbsoluteSize.Y + 15, 0, 25)
	additionalIndex.Text = "+" .. (#items - maxOnHotbar)
	additionalIndex.Visible = (#items > maxOnHotbar)

	for index, tool in ipairs(items) do
		local toolCircle = Frame.Contents:FindFirstChild(index)
		local isEquipped = (tool.Parent == Character)

		if not toolCircle then
			return
		end

		if tweens[toolCircle] then
			tweens[toolCircle]:Cancel()
			tweens[toolCircle] = nil
		end

		-- Adjust UIStroke Transparency based on whether the tool is equipped or not
		toolCircle.Background.Out.UIStroke.Transparency = isEquipped and 0 or 1
		-- Adjust BackgroundTransparency of the circle Frame based on the UIStroke Transparency
		toolCircle.Background.Out.BackgroundTransparency = isEquipped and 0.7 or 0.7
	end
end

local function create(tool)
	local nextIndex = (#items == 10) and 0 or #items
	local isVisible = (maxOnHotbar == 10) and (nextIndex <= 9 and true or false) or ((nextIndex ~= 0 and nextIndex <= maxOnHotbar) and true or false)

	local toolCircle = Template:Clone()
	toolCircle.LayoutOrder = #items
	toolCircle.Name = #items
	toolCircle.Size = UDim2.new(0, Frame.Contents.AbsoluteSize.Y, 0, Frame.Contents.AbsoluteSize.Y)
	toolCircle.Visible = isVisible
	toolCircle.Image.Image = tool.TextureId
	toolCircle.Index.Text = nextIndex
	toolCircle.FixedName.Text = tool.TextureId == "" and tool.Name or ""
	toolCircle.Parent = Frame.Contents

	toolCircle.Image.MouseButton1Click:Connect(function()
		handleEquip(tool)
	end)

	checkHotbar()
end

local function updateAdd(tool)
	if not tool:IsA("Tool") then
		return
	end

	checkHotbar()

	if table.find(items, tool) then
		return
	end

	table.insert(items, tool)

	create(tool)
end

local function updateRemove(tool)
	if not tool:IsA("Tool") then
		return
	end

	if tool.Parent == Character or tool.Parent == Backpack then
		return
	end

	if table.find(items, tool) then
		local index = table.find(items, tool)
		local toolCircle = Frame.Contents:FindFirstChild(index)

		if toolCircle then
			toolCircle:Destroy()
		end

		table.remove(items, index)
		checkHotbar(index)
	end
end



while true do
	local success, err = pcall(function()
		StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
	end)
	if success then
		break
	end
	wait()
end

if maxOnHotbar > 10 then
	maxOnHotbar = 10
end

Template.Visible = true
Template.Parent = nil

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)

Template.Visible = true
Template.Parent = nil

Frame.UIStroke:Destroy()

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)
-- Adding the UIStroke effect
local stroke = Instance.new("UIStroke")
stroke.Color = Color3.new(0, 1, 0)  -- Green color
stroke.Thickness = 4
stroke.Transparency = 0.5  -- Adjust transparency as needed
stroke.Parent = Frame

thats a simple hotbar script so far I just want to know how i implement stacking for example if I pick up 2 apples it shows 2 by the apple icon.

1 Like

Oh thanks by the way in advance.

Maybe this? I edited how adding and removing works. There are repeated parts in your code for some reason but I decided to leave them, I also changed wait() to task.wait() and used math.clamp instead of if statements for maxOnHotbar variable. To get the amount of the tool the player has, do:

local ownedAmount = toolCircle:GetAttribte("Amount")

Here’s the code:

-- [ SETTINGS ] --

local backgroundColor = Color3.fromRGB(0, 132, 255) -- The color of each circle
local maxOnHotbar = 10 -- How many tools can be displayed. Setting this to more than 10 reverts to 10

-- [ END SETTINGS ] --

-- Don't edit if you don't know what you're doing --

local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local p = Players.LocalPlayer
local Backpack = p.Backpack
local Character = p.Character
local Frame = script.Parent.Frame
local Template = Frame.Contents.objTemplate

local COLOR_DARKER = 0.65
local KEY_DICTIONARY = { Zero = 10, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9 }
local EQUIP_TWEENINFO = TweenInfo.new(0.25, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
local items = {}
local tweens = {}


local function handleEquip(tool)
	if tool.Parent ~= Character then
		Character.Humanoid:EquipTool(tool)
	else
		Character.Humanoid:UnequipTools()
	end
end


local function checkHotbar(removeIndex)
	if removeIndex then
		for _, toolCircle in pairs(Frame.Contents:GetChildren()) do
			if toolCircle:IsA("GuiObject") then
				if tonumber(toolCircle.Name) >= removeIndex then
					local newIndex = (tonumber(toolCircle.Name) == 11) and 0 or tonumber(toolCircle.Name) - 1
					local isVisible = (maxOnHotbar == 10) and (newIndex <= 9 and true or false) or ((newIndex ~= 0 and newIndex <= maxOnHotbar) and true or false)

					toolCircle.LayoutOrder -= 1
					toolCircle.Name -= 1
					toolCircle.Visible = isVisible
					toolCircle.Index.Text = newIndex
				end
			end
		end
	end

	local additionalIndex = Frame.AdditionalIndex
	additionalIndex.Size = UDim2.new(0, Frame.Contents.UIListLayout.AbsoluteContentSize.X + Frame.Contents.AbsoluteSize.Y + 15, 0, 25)
	additionalIndex.Text = "+" .. (#items - maxOnHotbar)
	additionalIndex.Visible = (#items > maxOnHotbar)

	for index, tool in ipairs(items) do
		local toolCircle = Frame.Contents:FindFirstChild(index)
		local isEquipped = (tool.Parent == Character)

		if not toolCircle then
			return
		end

		if tweens[toolCircle] then
			tweens[toolCircle]:Cancel()
			tweens[toolCircle] = nil
		end

		-- Adjust UIStroke Transparency based on whether the tool is equipped or not
		toolCircle.Background.Out.UIStroke.Transparency = isEquipped and 0 or 1
		-- Adjust BackgroundTransparency of the circle Frame based on the UIStroke Transparency
		toolCircle.Background.Out.BackgroundTransparency = isEquipped and 0.7 or 0.7
	end
end

local function create(tool)
	local _toolCircle = Frame.Contents:FindFirstChild(`{tool.Name}{index}`)
	
	if _toolCircle then
		_toolCircle:SetAttribute("Amount", _toolCircle:GetAttribte("Amount") + 1)
		return
	end

	local nextIndex = (#items == 10) and 0 or #items
	local isVisible = (maxOnHotbar == 10) and (nextIndex <= 9 and true or false) or ((nextIndex ~= 0 and nextIndex <= maxOnHotbar) and true or false)

	local toolCircle = Template:Clone()
	toolCircle.LayoutOrder = #items
	toolCircle.Name = `{tool.Name}{#items}`
	toolCircle.Size = UDim2.new(0, Frame.Contents.AbsoluteSize.Y, 0, Frame.Contents.AbsoluteSize.Y)
	toolCircle.Visible = isVisible
	toolCircle.Image.Image = tool.TextureId
	toolCircle.Index.Text = nextIndex
	toolCircle.FixedName.Text = tool.TextureId == "" and tool.Name or ""
	toolCircle.Parent = Frame.Contents
	
	toolCircle:SetAttribute("Amount", 1)

	toolCircle.Image.MouseButton1Click:Connect(function()
		handleEquip(tool)
	end)

	checkHotbar()
end

local function updateAdd(tool)
	if not tool:IsA("Tool") then
		return
	end

	checkHotbar()

	if table.find(items, tool) then
		return
	end

	table.insert(items, tool)

	create(tool)
end

local function updateRemove(tool)
	if not tool:IsA("Tool") then
		return
	end

	if tool.Parent == Character or tool.Parent == Backpack then
		return
	end

	if table.find(items, tool) then
		local index = table.find(items, tool)
		local toolCircle = Frame.Contents:FindFirstChild(`{tool.Name}{index}`)

		if toolCircle then
			toolCircle:Destroy()
		end

		table.remove(items, index)
		checkHotbar(index)
	end
end



while true do
	local success, err = pcall(function()
		StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
	end)
	if success then
		break
	end
	task.wait()
end

maxOnHotbar = math.clamp(maxOnHotbar, 0, 10)

Template.Visible = true
Template.Parent = nil

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)

Template.Visible = true
Template.Parent = nil

Frame.UIStroke:Destroy()

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)
-- Adding the UIStroke effect
local stroke = Instance.new("UIStroke")
stroke.Color = Color3.new(0, 1, 0)  -- Green color
stroke.Thickness = 4
stroke.Transparency = 0.5  -- Adjust transparency as needed
stroke.Parent = Frame
1 Like

I have a stacks text and the items stack but the text says nil when i pick up a tool


Screenshot 2023-09-26 at 9.28.54 PM
here is my script rn

-- [ SETTINGS ] --

local backgroundColor = Color3.fromRGB(0, 132, 255) -- The color of each circle
local maxOnHotbar = 10 -- How many tools can be displayed. Setting this to more than 10 reverts to 10

-- [ END SETTINGS ] --

-- Don't edit if you don't know what you're doing --

local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local p = Players.LocalPlayer
local Backpack = p.Backpack
local Character = p.Character
local Frame = script.Parent.Frame
local Template = Frame.Contents.objTemplate

local COLOR_DARKER = 0.65
local KEY_DICTIONARY = { Zero = 10, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9 }
local EQUIP_TWEENINFO = TweenInfo.new(0.25, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
local items = {}
local tweens = {}


local function handleEquip(tool)
	if tool.Parent ~= Character then
		Character.Humanoid:EquipTool(tool)
	else
		Character.Humanoid:UnequipTools()
	end
end


local function checkHotbar(removeIndex)
	if removeIndex then
		for _, toolCircle in pairs(Frame.Contents:GetChildren()) do
			if toolCircle:IsA("GuiObject") then
				if tonumber(toolCircle.Name) >= removeIndex then
					local newIndex = (tonumber(toolCircle.Name) == 11) and 0 or tonumber(toolCircle.Name) - 1
					local isVisible = (maxOnHotbar == 10) and (newIndex <= 9 and true or false) or ((newIndex ~= 0 and newIndex <= maxOnHotbar) and true or false)

					toolCircle.LayoutOrder -= 1
					toolCircle.Name -= 1
					toolCircle.Visible = isVisible
					toolCircle.Index.Text = newIndex
				end
			end
		end
	end

	local additionalIndex = Frame.AdditionalIndex
	additionalIndex.Size = UDim2.new(0, Frame.Contents.UIListLayout.AbsoluteContentSize.X + Frame.Contents.AbsoluteSize.Y + 15, 0, 25)
	additionalIndex.Text = "+" .. (#items - maxOnHotbar)
	additionalIndex.Visible = (#items > maxOnHotbar)

	for index, tool in ipairs(items) do
		local toolCircle = Frame.Contents:FindFirstChild(index)
		local isEquipped = (tool.Parent == Character)

		if not toolCircle then
			return
		end

		if tweens[toolCircle] then
			tweens[toolCircle]:Cancel()
			tweens[toolCircle] = nil
		end

		-- Adjust UIStroke Transparency based on whether the tool is equipped or not
		toolCircle.Background.Out.UIStroke.Transparency = isEquipped and 0 or 1
		-- Adjust BackgroundTransparency of the circle Frame based on the UIStroke Transparency
		toolCircle.Background.Out.BackgroundTransparency = isEquipped and 0.7 or 0.7
	end
end

local toolStacks = {}

local function create(tool)
	local toolName = tool.Name
	if toolStacks[toolName] then
		toolStacks[toolName] = toolStacks[toolName] + 1
		local toolCircle = Frame.Contents:FindFirstChild(toolName .. #items)

		if toolCircle then
			toolCircle.Stacks.Text = tostring(toolStacks[toolName])  -- Update stack count text
		end
	else
		local nextIndex = (#items == 10) and 0 or #items
		local isVisible = (maxOnHotbar == 10) and (nextIndex <= 9 and true or false) or ((nextIndex ~= 0 and nextIndex <= maxOnHotbar) and true or false)

		local toolCircle = Template:Clone()
		toolCircle.LayoutOrder = #items
		toolCircle.Name = toolName .. #items
		toolCircle.Size = UDim2.new(0, Frame.Contents.AbsoluteSize.Y, 0, Frame.Contents.AbsoluteSize.Y)
		toolCircle.Visible = isVisible
		toolCircle.Image.Image = tool.TextureId
		toolCircle.Index.Text = nextIndex
		toolCircle.Stacks.Text = tostring(toolStacks[toolName])  -- Initialize the stack count correctly
		toolCircle.Parent = Frame.Contents

		toolStacks[toolName] = 1
	end

	checkHotbar()
end


local function updateAdd(tool)
	if not tool:IsA("Tool") then
		return
	end

	checkHotbar()

	if table.find(items, tool) then
		return
	end

	table.insert(items, tool)

	create(tool)
end

-- Create a dictionary to store tool stacks

local function updateRemove(tool)
	if not tool:IsA("Tool") then
		return
	end

	if tool.Parent == Character or tool.Parent == Backpack then
		return
	end

	if toolStacks[tool.Name] then
		toolStacks[tool.Name] = toolStacks[tool.Name] - 1

		if toolStacks[tool.Name] <= 0 then
			local index = table.find(items, tool)
			local toolCircle = Frame.Contents:FindFirstChild(tool.Name .. index)

			if toolCircle then
				toolCircle:Destroy()
			end

			table.remove(items, index)
			checkHotbar(index)
		else
			-- Update the stack count text on the tool icon
			local index = table.find(items, tool)
			local toolCircle = Frame.Contents:FindFirstChild(tool.Name .. index)

			if toolCircle then
				toolCircle.Stacks.Text = toolStacks[tool.Name]
			end
		end
	end
end


while true do
	local success, err = pcall(function()
		StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
	end)
	if success then
		break
	end
	task.wait()
end

maxOnHotbar = math.clamp(maxOnHotbar, 0, 10)

Template.Visible = true
Template.Parent = nil

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)

Template.Visible = true
Template.Parent = nil

Frame.UIStroke:Destroy()

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)
-- Adding the UIStroke effect
local stroke = Instance.new("UIStroke")
stroke.Color = Color3.new(0, 1, 0)  -- Green color
stroke.Thickness = 4
stroke.Transparency = 0.5  -- Adjust transparency as needed
stroke.Parent = Frame

I didn’t see that part. Here’s the edited code.

-- [ SETTINGS ] --

local backgroundColor = Color3.fromRGB(0, 132, 255) -- The color of each circle
local maxOnHotbar = 10 -- How many tools can be displayed. Setting this to more than 10 reverts to 10

-- [ END SETTINGS ] --

-- Don't edit if you don't know what you're doing --

local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local p = Players.LocalPlayer
local Backpack = p.Backpack
local Character = p.Character
local Frame = script.Parent.Frame
local Template = Frame.Contents.objTemplate

local COLOR_DARKER = 0.65
local KEY_DICTIONARY = { Zero = 10, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9 }
local EQUIP_TWEENINFO = TweenInfo.new(0.25, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
local items = {}
local tweens = {}


local function handleEquip(tool)
	if tool.Parent ~= Character then
		Character.Humanoid:EquipTool(tool)
	else
		Character.Humanoid:UnequipTools()
	end
end


local function checkHotbar(removeIndex)
	if removeIndex then
		for _, toolCircle in pairs(Frame.Contents:GetChildren()) do
			if toolCircle:IsA("GuiObject") then
				if tonumber(toolCircle.Name) >= removeIndex then
					local newIndex = (tonumber(toolCircle.Name) == 11) and 0 or tonumber(toolCircle.Name) - 1
					local isVisible = (maxOnHotbar == 10) and (newIndex <= 9 and true or false) or ((newIndex ~= 0 and newIndex <= maxOnHotbar) and true or false)

					toolCircle.LayoutOrder -= 1
					toolCircle.Name -= 1
					toolCircle.Visible = isVisible
					toolCircle.Index.Text = newIndex
				end
			end
		end
	end

	local additionalIndex = Frame.AdditionalIndex
	additionalIndex.Size = UDim2.new(0, Frame.Contents.UIListLayout.AbsoluteContentSize.X + Frame.Contents.AbsoluteSize.Y + 15, 0, 25)
	additionalIndex.Text = "+" .. (#items - maxOnHotbar)
	additionalIndex.Visible = (#items > maxOnHotbar)

	for index, tool in ipairs(items) do
		local toolCircle = Frame.Contents:FindFirstChild(index)
		local isEquipped = (tool.Parent == Character)

		if not toolCircle then
			return
		end

		if tweens[toolCircle] then
			tweens[toolCircle]:Cancel()
			tweens[toolCircle] = nil
		end

		-- Adjust UIStroke Transparency based on whether the tool is equipped or not
		toolCircle.Background.Out.UIStroke.Transparency = isEquipped and 0 or 1
		-- Adjust BackgroundTransparency of the circle Frame based on the UIStroke Transparency
		toolCircle.Background.Out.BackgroundTransparency = isEquipped and 0.7 or 0.7
	end
end

local function create(tool)
	local _toolCircle = Frame.Contents:FindFirstChild(`{tool.Name}{index}`)
	
	 
	
	if _toolCircle then
		_toolCircle:SetAttribute("Amount", _toolCircle:GetAttribte("Amount") + 1)
		_toolCircle.Stacks.Text = tostring(_toolCircle:GetAttribte("Amount"))
		
		return
	end

	local nextIndex = (#items == 10) and 0 or #items
	local isVisible = (maxOnHotbar == 10) and (nextIndex <= 9 and true or false) or ((nextIndex ~= 0 and nextIndex <= maxOnHotbar) and true or false)

	local toolCircle = Template:Clone()
	toolCircle.LayoutOrder = #items
	toolCircle.Name = `{tool.Name}{#items}`
	toolCircle.Size = UDim2.new(0, Frame.Contents.AbsoluteSize.Y, 0, Frame.Contents.AbsoluteSize.Y)
	toolCircle.Visible = isVisible
	toolCircle.Image.Image = tool.TextureId
	toolCircle.Index.Text = nextIndex
	toolCircle.Stacks.Text = "1"
	toolCircle.FixedName.Text = tool.TextureId == "" and tool.Name or ""
	toolCircle.Parent = Frame.Contents
	
	toolCircle:SetAttribute("Amount", 1)

	toolCircle.Image.MouseButton1Click:Connect(function()
		handleEquip(tool)
	end)

	checkHotbar()
end

local function updateAdd(tool)
	if not tool:IsA("Tool") then
		return
	end

	checkHotbar()

	if table.find(items, tool) then
		return
	end

	table.insert(items, tool)

	create(tool)
end

local function updateRemove(tool)
	if not tool:IsA("Tool") then
		return
	end

	if tool.Parent == Character or tool.Parent == Backpack then
		return
	end

	if table.find(items, tool) then
		local index = table.find(items, tool)
		local toolCircle = Frame.Contents:FindFirstChild(`{tool.Name}{index}`)

		if toolCircle then
			local amount = toolCircle:GetAttribute("Amount")
			
			if amount > 1 then
				toolCircle.Stacks.Text = tostring(amount - 1)
			else
				toolCircle:Destroy()
			end
			
			toolCircle:SetAttribute("Amount", amount - 1)
		end

		table.remove(items, index)
		checkHotbar(index)
	end
end



while true do
	local success, err = pcall(function()
		StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
	end)
	if success then
		break
	end
	task.wait()
end

maxOnHotbar = math.clamp(maxOnHotbar, 0, 10)

Template.Visible = true
Template.Parent = nil

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)

Template.Visible = true
Template.Parent = nil

Frame.UIStroke:Destroy()

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)
-- Adding the UIStroke effect
local stroke = Instance.new("UIStroke")
stroke.Color = Color3.new(0, 1, 0)  -- Green color
stroke.Thickness = 4
stroke.Transparency = 0.5  -- Adjust transparency as needed
stroke.Parent = Frame

Screenshot 2023-09-26 at 9.36.02 PM
now theres this issue where they make a new hotbar slot for each apple and give themselves 1 stack.

-- [ SETTINGS ] --

local backgroundColor = Color3.fromRGB(0, 132, 255) -- The color of each circle
local maxOnHotbar = 10 -- How many tools can be displayed. Setting this to more than 10 reverts to 10

-- [ END SETTINGS ] --

-- Don't edit if you don't know what you're doing --

local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local p = Players.LocalPlayer
local Backpack = p.Backpack
local Character = p.Character
local Frame = script.Parent.Frame
local Template = Frame.Contents.objTemplate

local COLOR_DARKER = 0.65
local KEY_DICTIONARY = { Zero = 10, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9 }
local EQUIP_TWEENINFO = TweenInfo.new(0.25, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
local items = {}
local tweens = {}


local function handleEquip(tool)
	if tool.Parent ~= Character then
		Character.Humanoid:EquipTool(tool)
	else
		Character.Humanoid:UnequipTools()
	end
end


local function checkHotbar(removeIndex)
	if removeIndex then
		for _, toolCircle in pairs(Frame.Contents:GetChildren()) do
			if toolCircle:IsA("GuiObject") then
				if tonumber(toolCircle.Name) >= removeIndex then
					local newIndex = (tonumber(toolCircle.Name) == 11) and 0 or tonumber(toolCircle.Name) - 1
					local isVisible = (maxOnHotbar == 10) and (newIndex <= 9 and true or false) or ((newIndex ~= 0 and newIndex <= maxOnHotbar) and true or false)

					toolCircle.LayoutOrder -= 1
					toolCircle.Name -= 1
					toolCircle.Visible = isVisible
					toolCircle.Index.Text = newIndex
				end
			end
		end
	end

	local additionalIndex = Frame.AdditionalIndex
	additionalIndex.Size = UDim2.new(0, Frame.Contents.UIListLayout.AbsoluteContentSize.X + Frame.Contents.AbsoluteSize.Y + 15, 0, 25)
	additionalIndex.Text = "+" .. (#items - maxOnHotbar)
	additionalIndex.Visible = (#items > maxOnHotbar)

	for index, tool in ipairs(items) do
		local toolCircle = Frame.Contents:FindFirstChild(index)
		local isEquipped = (tool.Parent == Character)

		if not toolCircle then
			return
		end

		if tweens[toolCircle] then
			tweens[toolCircle]:Cancel()
			tweens[toolCircle] = nil
		end

		-- Adjust UIStroke Transparency based on whether the tool is equipped or not
		toolCircle.Background.Out.UIStroke.Transparency = isEquipped and 0 or 1
		-- Adjust BackgroundTransparency of the circle Frame based on the UIStroke Transparency
		toolCircle.Background.Out.BackgroundTransparency = isEquipped and 0.7 or 0.7
	end
end

local function create(tool)
	local index = table.find(items, tool)
	local _toolCircle = Frame.Contents:FindFirstChild(`{tool.Name}{index}`)
	
	if _toolCircle then
		_toolCircle:SetAttribute("Amount", _toolCircle:GetAttribte("Amount") + 1)
		_toolCircle.Stacks.Text = tostring(_toolCircle:GetAttribte("Amount"))
		
		return
	end

	local nextIndex = (#items == 10) and 0 or #items
	local isVisible = (maxOnHotbar == 10) and (nextIndex <= 9 and true or false) or ((nextIndex ~= 0 and nextIndex <= maxOnHotbar) and true or false)

	local toolCircle = Template:Clone()
	toolCircle.LayoutOrder = #items
	toolCircle.Name = `{tool.Name}{#items}`
	toolCircle.Size = UDim2.new(0, Frame.Contents.AbsoluteSize.Y, 0, Frame.Contents.AbsoluteSize.Y)
	toolCircle.Visible = isVisible
	toolCircle.Image.Image = tool.TextureId
	toolCircle.Index.Text = nextIndex
	toolCircle.Stacks.Text = "1"
	toolCircle.FixedName.Text = tool.TextureId == "" and tool.Name or ""
	toolCircle.Parent = Frame.Contents
	
	toolCircle:SetAttribute("Amount", 1)

	toolCircle.Image.MouseButton1Click:Connect(function()
		handleEquip(tool)
	end)

	checkHotbar()
end

local function updateAdd(tool)
	if not tool:IsA("Tool") then
		return
	end

	checkHotbar()

	if table.find(items, tool) then
		return
	end

	table.insert(items, tool)

	create(tool)
end

local function updateRemove(tool)
	if not tool:IsA("Tool") then
		return
	end

	if tool.Parent == Character or tool.Parent == Backpack then
		return
	end

	if table.find(items, tool) then
		local index = table.find(items, tool)
		local toolCircle = Frame.Contents:FindFirstChild(`{tool.Name}{index}`)

		if toolCircle then
			local amount = toolCircle:GetAttribute("Amount")
			
			if amount > 1 then
				toolCircle.Stacks.Text = tostring(amount - 1)
			else
				toolCircle:Destroy()
			end
			
			toolCircle:SetAttribute("Amount", amount - 1)
		end

		table.remove(items, index)
		checkHotbar(index)
	end
end



while true do
	local success, err = pcall(function()
		StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
	end)
	if success then
		break
	end
	task.wait()
end

maxOnHotbar = math.clamp(maxOnHotbar, 0, 10)

Template.Visible = true
Template.Parent = nil

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)

Template.Visible = true
Template.Parent = nil

Frame.UIStroke:Destroy()

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)
-- Adding the UIStroke effect
local stroke = Instance.new("UIStroke")
stroke.Color = Color3.new(0, 1, 0)  -- Green color
stroke.Thickness = 4
stroke.Transparency = 0.5  -- Adjust transparency as needed
stroke.Parent = Frameprint("Hello World!")
1 Like
local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local p = Players.LocalPlayer
local Backpack = p.Backpack
local Character = p.Character
local Frame = script.Parent.Frame
local Template = Frame.Contents.objTemplate

local COLOR_DARKER = 0.65
local KEY_DICTIONARY = { Zero = 10, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9 }
local EQUIP_TWEENINFO = TweenInfo.new(0.25, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
local items = {}
local tweens = {}

-- Stacking-related variables and functions
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local maxOnHotbar = 10 -- How many tools can be displayed. Setting this to more than 10 reverts to 10

-- Create a function to handle stacking UI
local function handleStackingUI(toolCircle, tool)
	if tool:FindFirstChild('stacks') then
		toolCircle.Stacks.Text = tool.stacks.Value
		tool.stacks:GetPropertyChangedSignal('Value'):Connect(function()
			toolCircle.Stacks.Text = tool.stacks.Value
		end)
	end
end

-- Function to handle equipping tools
local function handleEquip(tool)
	if tool.Parent ~= Character then
		Character.Humanoid:EquipTool(tool)
	else
		Character.Humanoid:UnequipTools()
	end
end

-- Function to check and update the hotbar UI
local function checkHotbar(removeIndex)
	for _, toolCircle in pairs(Frame.Contents:GetChildren()) do
		if toolCircle:IsA("GuiObject") then
			if tonumber(toolCircle.Name) >= removeIndex then
				local newIndex = (tonumber(toolCircle.Name) == 11) and 0 or tonumber(toolCircle.Name) - 1
				local isVisible = (maxOnHotbar == 10) and (newIndex <= 9 and true or false) or ((newIndex ~= 0 and newIndex <= maxOnHotbar) and true or false)

				toolCircle.LayoutOrder -= 1
				toolCircle.Name -= 1
				toolCircle.Visible = isVisible
				toolCircle.Index.Text = newIndex
			end
		end
	end

	local additionalIndex = Frame.AdditionalIndex
	additionalIndex.Size = UDim2.new(0, Frame.Contents.UIListLayout.AbsoluteContentSize.X + Frame.Contents.AbsoluteSize.Y + 15, 0, 25)
	additionalIndex.Text = "+" .. (#items - maxOnHotbar)
	additionalIndex.Visible = (#items > maxOnHotbar)

	for index, tool in ipairs(items) do
		local toolCircle = Frame.Contents:FindFirstChild(index)
		local isEquipped = (tool.Parent == Character)

		if not toolCircle then
			return
		end

		if tweens[toolCircle] then
			tweens[toolCircle]:Cancel()
			tweens[toolCircle] = nil
		end

		-- Adjust UIStroke Transparency based on whether the tool is equipped or not
		toolCircle.Background.Out.UIStroke.Transparency = isEquipped and 0 or 1
		-- Adjust BackgroundTransparency of the circle Frame based on the UIStroke Transparency
		toolCircle.Background.Out.BackgroundTransparency = isEquipped and 0.7 or 0.7

		-- Handle stacking UI
		handleStackingUI(toolCircle, tool)
	end
end

local function create(tool)
	local nextIndex = (#items == 10) and 0 or #items
	local isVisible = (maxOnHotbar == 10) and (nextIndex <= 9 and true or false) or ((nextIndex ~= 0 and nextIndex <= maxOnHotbar) and true or false)

	local toolCircle = Template:Clone()
	toolCircle.LayoutOrder = #items
	toolCircle.Name = #items
	toolCircle.Size = UDim2.new(0, Frame.Contents.AbsoluteSize.Y, 0, Frame.Contents.AbsoluteSize.Y)
	toolCircle.Visible = isVisible
	toolCircle.Image.Image = tool.TextureId
	toolCircle.Index.Text = nextIndex
	toolCircle.FixedName.Text = tool.TextureId == "" and tool.Name or ""
	toolCircle.Parent = Frame.Contents

	toolCircle.Image.MouseButton1Click:Connect(function()
		handleEquip(tool)
	end)

	checkHotbar()
end

local function updateAdd(tool)
	if not tool:IsA("Tool") then
		return
	end

	checkHotbar()

	if table.find(items, tool) then
		return
	end

	table.insert(items, tool)

	create(tool)
end

local function updateRemove(tool)
	if not tool:IsA("Tool") then
		return
	end

	if tool.Parent == Character or tool.Parent == Backpack then
		return
	end

	if table.find(items, tool) then
		local index = table.find(items, tool)
		local toolCircle = Frame.Contents:FindFirstChild(index)

		if toolCircle then
			toolCircle:Destroy()
		end

		table.remove(items, index)
		checkHotbar(index)
	end
end

while true do
	local success, err = pcall(function()
		StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
	end)
	if success then
		break
	end
	wait()
end

if maxOnHotbar > 10 then
	maxOnHotbar = 10
end

Template.Visible = true
Template.Parent = nil

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)

Template.Visible = true
Template.Parent = nil

Frame.UIStroke:Destroy()

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)

this is my current script, nothing seems to be working to get this thing stacking. do you want the file for the place?

1 Like

Just use the code I gave u-
I have provided u with the code multiple times and u haven’t used it at all. If you don’t want to use it just say you won’t use instead of sending me different scripts each time.

well the codes you are sending me dont work plug them into the test place i gave you.

this is the file with the inventory ui.

Then send me the problems in it and don’t send me different codes.

Edit the stacks label to have the name “Stacks” and change the code to this:

-- [ SETTINGS ] --

local backgroundColor = Color3.fromRGB(0, 132, 255) -- The color of each circle
local maxOnHotbar = 10 -- How many tools can be displayed. Setting this to more than 10 reverts to 10

-- [ END SETTINGS ] --

-- Don't edit if you don't know what you're doing --

local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local p = Players.LocalPlayer
local Backpack = p.Backpack
local Character = p.Character
local Frame = script.Parent.Frame
local Template = Frame.Contents.objTemplate

local COLOR_DARKER = 0.65
local KEY_DICTIONARY = { Zero = 10, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9 }
local EQUIP_TWEENINFO = TweenInfo.new(0.25, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
local items = {}
local tweens = {}


local function handleEquip(tool)
	if tool.Parent ~= Character then
		Character.Humanoid:EquipTool(tool)
	else
		Character.Humanoid:UnequipTools()
	end
end


local function checkHotbar(removeIndex)
	if removeIndex then
		for _, toolCircle in pairs(Frame.Contents:GetChildren()) do
			if toolCircle:IsA("GuiObject") then
				if tonumber(toolCircle.Name) >= removeIndex then
					local newIndex = (tonumber(toolCircle.Name) == 11) and 0 or tonumber(toolCircle.Name) - 1
					local isVisible = (maxOnHotbar == 10) and (newIndex <= 9 and true or false) or ((newIndex ~= 0 and newIndex <= maxOnHotbar) and true or false)

					toolCircle.LayoutOrder -= 1
					toolCircle.Name -= 1
					toolCircle.Visible = isVisible
					toolCircle.Index.Text = newIndex
				end
			end
		end
	end

	local additionalIndex = Frame.AdditionalIndex
	additionalIndex.Size = UDim2.new(0, Frame.Contents.UIListLayout.AbsoluteContentSize.X + Frame.Contents.AbsoluteSize.Y + 15, 0, 25)
	additionalIndex.Text = "+" .. (#items - maxOnHotbar)
	additionalIndex.Visible = (#items > maxOnHotbar)

	for index, tool in ipairs(items) do
		local toolCircle = Frame.Contents:FindFirstChild(index)
		local isEquipped = (tool.Parent == Character)

		if not toolCircle then
			return
		end

		if tweens[toolCircle] then
			tweens[toolCircle]:Cancel()
			tweens[toolCircle] = nil
		end

		-- Adjust UIStroke Transparency based on whether the tool is equipped or not
		toolCircle.Background.Out.UIStroke.Transparency = isEquipped and 0 or 1
		-- Adjust BackgroundTransparency of the circle Frame based on the UIStroke Transparency
		toolCircle.Background.Out.BackgroundTransparency = isEquipped and 0.7 or 0.7
	end
end

local function create(tool)
	local index = 0
	
	for i, v in ipairs(items) do
		if v.Name == tool.Name then index = i break end
	end
	
	local _toolCircle = Frame.Contents:FindFirstChild(`{tool.Name}{index}`)

	if _toolCircle then
		_toolCircle:SetAttribute("Amount", _toolCircle:GetAttribute("Amount") + 1)
		_toolCircle.Stacks.Text = tostring(_toolCircle:GetAttribute("Amount"))

		return
	end

	local nextIndex = (#items == 10) and 0 or #items
	local isVisible = (maxOnHotbar == 10) and (nextIndex <= 9 and true or false) or ((nextIndex ~= 0 and nextIndex <= maxOnHotbar) and true or false)

	local toolCircle = Template:Clone()
	toolCircle.LayoutOrder = #items
	toolCircle.Name = `{tool.Name}{#items}`
	toolCircle.Size = UDim2.new(0, Frame.Contents.AbsoluteSize.Y, 0, Frame.Contents.AbsoluteSize.Y)
	toolCircle.Visible = isVisible
	toolCircle.Image.Image = tool.TextureId
	toolCircle.Index.Text = nextIndex
	toolCircle.Stacks.Text = "1"
	toolCircle.FixedName.Text = tool.TextureId == "" and tool.Name or ""
	toolCircle.Parent = Frame.Contents

	toolCircle:SetAttribute("Amount", 1)

	toolCircle.Image.MouseButton1Click:Connect(function()
		handleEquip(tool)
	end)

	checkHotbar()
end

local function updateAdd(tool)
	if not tool:IsA("Tool") then
		return
	end

	checkHotbar()

	if table.find(items, tool) then
		return
	end

	table.insert(items, tool)

	create(tool)
end

local function updateRemove(tool)
	if not tool:IsA("Tool") then
		return
	end

	if tool.Parent == Character or tool.Parent == Backpack then
		return
	end

	if table.find(items, tool) then
		local index = table.find(items, tool)
		local toolCircle = Frame.Contents:FindFirstChild(`{tool.Name}{index}`)

		if toolCircle then
			local amount = toolCircle:GetAttribute("Amount")

			if amount > 1 then
				toolCircle.Stacks.Text = tostring(amount - 1)
			else
				toolCircle:Destroy()
			end

			toolCircle:SetAttribute("Amount", amount - 1)
		end

		table.remove(items, index)
		checkHotbar(index)
	end
end



while true do
	local success, err = pcall(function()
		StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
	end)
	if success then
		break
	end
	task.wait()
end

maxOnHotbar = math.clamp(maxOnHotbar, 0, 10)

Template.Visible = true
Template.Parent = nil

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)
-- Adding the UIStroke effect
local stroke = Instance.new("UIStroke")
stroke.Color = Color3.new(0, 1, 0)  -- Green color
stroke.Thickness = 4
stroke.Transparency = 0.5  -- Adjust transparency as needed
stroke.Parent = Frame

Here you go! I removed a lot of unnecessary code too.

-- [ SETTINGS ] --

local backgroundColor = Color3.fromRGB(0, 132, 255) -- The color of each circle
local maxOnHotbar = 10 -- How many tools can be displayed. Setting this to more than 10 reverts to 10

-- [ END SETTINGS ] --

-- Don't edit if you don't know what you're doing --

local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local p = Players.LocalPlayer
local Backpack = p.Backpack
local Character = p.Character
local Frame = script.Parent.Frame
local Template = Frame.Contents.objTemplate

local COLOR_DARKER = 0.65
local KEY_DICTIONARY = { Zero = 10, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9 }
local EQUIP_TWEENINFO = TweenInfo.new(0.25, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
local items = {}
local tweens = {}


local function handleEquip(tool)
	print(items)
	if tool.Parent ~= Character then
		Character.Humanoid:EquipTool(tool)
	else
		Character.Humanoid:UnequipTools()
	end
end


local function checkHotbar(removeIndex)
	if removeIndex then
		for _, toolCircle in pairs(Frame.Contents:GetChildren()) do
			if toolCircle:IsA("GuiObject") then
				local circleName = tonumber(toolCircle.Name)
				if circleName and circleName >= removeIndex then
					local newIndex = (circleName == 11) and 0 or circleName - 1
					local isVisible = (maxOnHotbar == 10) and (newIndex <= 9 and true or false) or ((newIndex ~= 0 and newIndex <= maxOnHotbar) and true or false)

					toolCircle.LayoutOrder -= 1
					toolCircle.Name = tostring(newIndex)
					toolCircle.Visible = isVisible
					toolCircle.Index.Text = tostring(newIndex)
				end
			end
		end
	end

	local additionalIndex = Frame.AdditionalIndex
	additionalIndex.Size = UDim2.new(0, Frame.Contents.UIListLayout.AbsoluteContentSize.X + Frame.Contents.AbsoluteSize.Y + 15, 0, 25)
	additionalIndex.Text = "+" .. math.max(0, #items - maxOnHotbar)
	additionalIndex.Visible = (#items > maxOnHotbar)

	for index, tool in ipairs(items) do
		local toolCircle = Frame.Contents:FindFirstChild(tostring(index))
		local isEquipped = (tool.Parent == Character)

		if not toolCircle then
			return
		end

		if tweens[toolCircle] then
			tweens[toolCircle]:Cancel()
			tweens[toolCircle] = nil
		end

		-- Adjust UIStroke Transparency based on whether the tool is equipped or not
		toolCircle.Background.Out.UIStroke.Transparency = isEquipped and 0 or 1
		-- Adjust BackgroundTransparency of the circle Frame based on the UIStroke Transparency
		toolCircle.Background.Out.BackgroundTransparency = isEquipped and 0.7 or 0.7
	end
end


local function create(tool)
	local index = 0

	for i, v in ipairs(items) do
		if v.Name == tool.Name then index = i break end
	end

	local _toolCircle = Frame.Contents:FindFirstChild(`{tool.Name}{index}`)

	if _toolCircle then
		_toolCircle:SetAttribute("Amount", _toolCircle:GetAttribute("Amount") + 1)
		_toolCircle.Stacks.Text = tostring(_toolCircle:GetAttribute("Amount"))

		return
	end

	table.insert(items, tool)

	local nextIndex = (#items == 10) and 0 or #items
	local isVisible = (maxOnHotbar == 10) and (nextIndex <= 9 and true or false) or ((nextIndex ~= 0 and nextIndex <= maxOnHotbar) and true or false)

	local toolCircle = Template:Clone()
	toolCircle.LayoutOrder = #items
	toolCircle.Name = `{tool.Name}{#items}`
	toolCircle.Size = UDim2.new(0, Frame.Contents.AbsoluteSize.Y, 0, Frame.Contents.AbsoluteSize.Y)
	toolCircle.Visible = isVisible
	toolCircle.Image.Image = tool.TextureId
	toolCircle.Index.Text = nextIndex
	toolCircle.Stacks.Text = "1"
	toolCircle.FixedName.Text = tool.TextureId == "" and tool.Name or ""
	toolCircle.Parent = Frame.Contents

	toolCircle:SetAttribute("Amount", 1)

	toolCircle.Image.MouseButton1Click:Connect(function()
		handleEquip(tool)
	end)

	checkHotbar()
end

local function updateAdd(tool)
	if not tool:IsA("Tool") then
		return
	end

	checkHotbar()

	if table.find(items, tool) then
		return
	end

	create(tool)
end

local function updateRemove(tool)
	if not tool:IsA("Tool") then
		return
	end

	if tool.Parent == Character or tool.Parent == Backpack then
		return
	end

	if table.find(items, tool) then
		local index = table.find(items, tool)
		local toolCircle = Frame.Contents:FindFirstChild(`{tool.Name}{index}`)

		if toolCircle then
			local amount = toolCircle:GetAttribute("Amount")

			if amount > 1 then
				toolCircle.Stacks.Text = tostring(amount - 1)
			else
				toolCircle:Destroy()
			end

			toolCircle:SetAttribute("Amount", amount - 1)
		end

		table.remove(items, index)
		checkHotbar(index)
	end
end



while true do
	local success, err = pcall(function()
		StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
	end)
	if success then
		break
	end
	task.wait()
end

maxOnHotbar = math.clamp(maxOnHotbar, 0, 10)

Template.Visible = true
Template.Parent = nil

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)
-- Adding the UIStroke effect
local stroke = Instance.new("UIStroke")
stroke.Color = Color3.new(0, 1, 0)  -- Green color
stroke.Thickness = 4
stroke.Transparency = 0.5  -- Adjust transparency as needed
stroke.Parent = Frame
1 Like

The problem was you were setting the tool slot number based on how many tools that were in your inventory rather than how many unique tools there were. It looks like msix29 already beat me to it though :sweat_smile:

-- [ SETTINGS ] --

local backgroundColor = Color3.fromRGB(0, 132, 255) -- The color of each circle
local maxOnHotbar = 10 -- How many tools can be displayed. Setting this to more than 10 reverts to 10

-- [ END SETTINGS ] --

-- Don't edit if you don't know what you're doing --

local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local p = Players.LocalPlayer
local Backpack = p.Backpack
local Character = p.Character
local Frame = script.Parent.Frame
local Template = Frame.Contents.objTemplate

local COLOR_DARKER = 0.65
local KEY_DICTIONARY = { Zero = 10, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9 }
local EQUIP_TWEENINFO = TweenInfo.new(0.25, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
local items = {}
local tweens = {}


local function handleEquip(tool)
	if tool.Parent ~= Character then
		Character.Humanoid:EquipTool(tool)
	else
		Character.Humanoid:UnequipTools()
	end
end


local function checkHotbar(removeIndex)
	if removeIndex then
		for _, toolCircle in pairs(Frame.Contents:GetChildren()) do
			if toolCircle:IsA("GuiObject") then
				local circleName = tonumber(toolCircle.Name)
				if circleName and circleName >= removeIndex then
					local newIndex = (circleName == 11) and 0 or circleName - 1
					local isVisible = (maxOnHotbar == 10) and (newIndex <= 9 and true or false) or ((newIndex ~= 0 and newIndex <= maxOnHotbar) and true or false)

					toolCircle.LayoutOrder -= 1
					toolCircle.Name = tostring(newIndex)
					toolCircle.Visible = isVisible
					toolCircle.Index.Text = tostring(newIndex)
				end
			end
		end
	end

	local additionalIndex = Frame.AdditionalIndex
	additionalIndex.Size = UDim2.new(0, Frame.Contents.UIListLayout.AbsoluteContentSize.X + Frame.Contents.AbsoluteSize.Y + 15, 0, 25)
	additionalIndex.Text = "+" .. math.max(0, #items - maxOnHotbar)
	additionalIndex.Visible = (#items > maxOnHotbar)

	for index, tool in ipairs(items) do
		local toolCircle = Frame.Contents:FindFirstChild(tostring(index))
		local isEquipped = (tool.Parent == Character)

		if not toolCircle then
			return
		end

		if tweens[toolCircle] then
			tweens[toolCircle]:Cancel()
			tweens[toolCircle] = nil
		end

		-- Adjust UIStroke Transparency based on whether the tool is equipped or not
		toolCircle.Background.Out.UIStroke.Transparency = isEquipped and 0 or 1
		-- Adjust BackgroundTransparency of the circle Frame based on the UIStroke Transparency
		toolCircle.Background.Out.BackgroundTransparency = isEquipped and 0.7 or 0.7
	end
end


local function create(tool)
	local index = 0

	for i, v in ipairs(items) do
		if v.Name == tool.Name then index = i break end
	end

	local _toolCircle = Frame.Contents:FindFirstChild(`{tool.Name}{index}`)

	if _toolCircle then
		_toolCircle:SetAttribute("Amount", _toolCircle:GetAttribute("Amount") + 1)
		_toolCircle.Stacks.Text = tostring(_toolCircle:GetAttribute("Amount"))

		return
	end
	
	local newindex = {}
	
	for i,v in pairs(items) do
		local Insertable = true
		for i,b in pairs(newindex) do
			if b.Name == v.Name then
				Insertable = false
			end
		end
		if Insertable then
			table.insert(newindex, v)
		end
	end

	local nextIndex = (#items == 10) and 0 or #items
	local isVisible = (maxOnHotbar == 10) and (nextIndex <= 9 and true or false) or ((nextIndex ~= 0 and nextIndex <= maxOnHotbar) and true or false)

	local toolCircle = Template:Clone()
	toolCircle.LayoutOrder = #items
	toolCircle.Name = `{tool.Name}{#items}`
	toolCircle.Size = UDim2.new(0, Frame.Contents.AbsoluteSize.Y, 0, Frame.Contents.AbsoluteSize.Y)
	toolCircle.Visible = isVisible
	toolCircle.Image.Image = tool.TextureId
	toolCircle.Index.Text = #newindex
	toolCircle.Stacks.Text = "1"
	toolCircle.FixedName.Text = tool.TextureId == "" and tool.Name or ""
	toolCircle.Parent = Frame.Contents

	toolCircle:SetAttribute("Amount", 1)

	toolCircle.Image.MouseButton1Click:Connect(function()
		handleEquip(tool)
	end)

	checkHotbar()
end

local function updateAdd(tool)
	if not tool:IsA("Tool") then
		return
	end

	checkHotbar()

	if table.find(items, tool) then
		return
	end

	table.insert(items, tool)

	create(tool)
end

local function updateRemove(tool)
	if not tool:IsA("Tool") then
		return
	end

	if tool.Parent == Character or tool.Parent == Backpack then
		return
	end

	if table.find(items, tool) then
		local index = table.find(items, tool)
		local toolCircle = Frame.Contents:FindFirstChild(`{tool.Name}{index}`)

		if toolCircle then
			local amount = toolCircle:GetAttribute("Amount")

			if amount > 1 then
				toolCircle.Stacks.Text = tostring(amount - 1)
			else
				toolCircle:Destroy()
			end

			toolCircle:SetAttribute("Amount", amount - 1)
		end

		table.remove(items, index)
		checkHotbar(index)
	end
end



while true do
	local success, err = pcall(function()
		StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
	end)
	if success then
		break
	end
	task.wait()
end

maxOnHotbar = math.clamp(maxOnHotbar, 0, 10)

Template.Visible = true
Template.Parent = nil

for _, tool in pairs(Backpack:GetChildren()) do
	updateAdd(tool)
end
Backpack.ChildAdded:Connect(updateAdd)
Backpack.ChildRemoved:Connect(updateRemove)

Character.ChildAdded:Connect(updateAdd)
Character.ChildRemoved:Connect(updateRemove)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if KEY_DICTIONARY[input.KeyCode.Name] then
		local index = KEY_DICTIONARY[input.KeyCode.Name]

		if items[index] then
			handleEquip(items[index])
		end
	end
end)
-- Adding the UIStroke effect
local stroke = Instance.new("UIStroke")
stroke.Color = Color3.new(0, 1, 0)  -- Green color
stroke.Thickness = 4
stroke.Transparency = 0.5  -- Adjust transparency as needed
stroke.Parent = Frame
2 Likes

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