Need help on proper Tool Switching

Kind of hard situation to explain, but here are some video example of what I mean:

You may not noticed it at first, until you noticed that the tools only displayed 2, but for some reason when you switch back:

You’d able to see 3 tools that I exactly have in my backpack! Here’s a Full LocalScript:

local player = game:GetService("Players").LocalPlayer
local buttonFrame = script.Parent

local nextButton = buttonFrame.Next
local backButton = buttonFrame.Back

local mainFrame = player.PlayerGui.MainUI.ToolDisplay
local toolIcon = mainFrame.IfSome.ToolIcon
local toolName = mainFrame.IfSome.ToolName

local tools = player.Backpack:GetChildren()
local equippedToolIndex = 0

local function updateUI(tool)
	if tool then
		toolIcon.Image = tool.TextureId or ""
		toolName.Text = tool.Name
		mainFrame.IfSome.Visible = true
		mainFrame.ifNone.Visible = false
	else
		toolIcon.Image = "rbxassetid://0"
		toolName.Text = "Nil"
		mainFrame.IfSome.Visible = false
		mainFrame.ifNone.Visible = true
	end
end

local function equipTool(tool)
	player.Character:FindFirstChildOfClass("Humanoid"):UnequipTools()
	if tool then
		player.Backpack:FindFirstChild(tool.Name).Parent = player.Character
	end
	updateUI(tool)
end

local function nextTool()
	equippedToolIndex = equippedToolIndex + 1
	if equippedToolIndex > #tools then
		equippedToolIndex = 0
		equipTool(nil)
	else
		equipTool(tools[equippedToolIndex])
	end
end

local function previousTool()
	equippedToolIndex = equippedToolIndex - 1
	if equippedToolIndex < 0 then
		equippedToolIndex = #tools
	end
	if equippedToolIndex == 0 then
		equipTool(nil)
	else
		equipTool(tools[equippedToolIndex])
	end
end

player.Backpack.ChildAdded:Connect(function(tool)
	table.insert(tools, tool)
end)

player.Backpack.ChildRemoved:Connect(function(tool)
	for i, t in ipairs(tools) do
		if t == tool then
			table.remove(tools, i)
			break
		end
	end
	if equippedToolIndex > #tools then
		equippedToolIndex = 0
	end
end)

player.Character.ChildAdded:Connect(function(child)
	if child:IsA("Tool") then
		updateUI(child)
	end
end)

player.Character.ChildRemoved:Connect(function(child)
	if child:IsA("Tool") then
		updateUI(nil)
	end
end)

game:GetService("UserInputService").InputBegan:Connect(function(input, isTyping)
	if isTyping then return end
	if input.KeyCode == Enum.KeyCode.N then
		nextTool()
	elseif input.KeyCode == Enum.KeyCode.B then
		previousTool()
	end
end)

local function handleButtonEvents(button, toolAction)
	local function setTransparency(buttonTarget, transparency)
		buttonTarget.ImageTransparency = transparency
	end

	button.MouseButton1Down:Connect(function()
		setTransparency(button, 0)
		toolAction()
	end)

	button.MouseButton1Up:Connect(function()
		setTransparency(button, 0.5)
	end)

	button.MouseLeave:Connect(function()
		setTransparency(button, 0.5)
	end)

	game:GetService("GuiService").MenuOpened:Connect(function()
		setTransparency(button, 0.5)
	end)
end

handleButtonEvents(nextButton, nextTool)
handleButtonEvents(backButton, previousTool)
updateUI(nil)
3 Likes

Use a table to switch the tools rather than depending on the backpack.

1 Like

some of the line codes involves tables. Do you mean by adding all tool names to the table?

1 Like

Ah, no sorry. I read your code wrong. Let me try giving you a fix for the index part:

local function equipTool(tool)
	player.Character:FindFirstChildOfClass("Humanoid"):UnequipTools()
	tool = player.Backpack:FindFirstChild(tool)
	if tool then
		player.Character:FindFirstChildOfClass("Humanoid"):EquipTool(tool)
	end
	updateUI(tool)
end

table.insert(tools,"")

local function nextTool()
	equippedToolIndex = equippedToolIndex % #tools + 1
end

local function previousTool()
	equippedToolIndex = (equippedToolIndex - 1) % #tools
	if equippedToolIndex == 0 then
		equippedToolIndex = #tools
	end
	equipTool(tostring(tools[equippedToolIndex]))
end
1 Like

Unfortunately that didn’t work, BUT I think I’ve found the issue of this snippet code of mine here between line code 58 to 84…

player.Backpack.ChildAdded:Connect(function(tool)
	table.insert(tools, tool)
end)

player.Backpack.ChildRemoved:Connect(function(tool)
	for i, t in ipairs(tools) do
		if t == tool then
			table.remove(tools, i)
			break
		end
	end
	if equippedToolIndex > #tools then
		equippedToolIndex = 0
	end
end)

player.Character.ChildAdded:Connect(function(child)
	if child:IsA("Tool") then
		updateUI(child)
	end
end)

player.Character.ChildRemoved:Connect(function(child)
	if child:IsA("Tool") then
		updateUI(nil)
	end
end)

What this code does basically adds the new tool to the table, Down side though I am way too confused about this code, and don’t know how to resolve this

Wait, omg I again didn’t see it. Wow. I am sleepy today. That’s the issue then, The code adds a new tool to the end of the table, a good ray to do this is to just see if the tool gets parented from or to the charcter and then remove or add the tool accordingly.

Something like:

local lastTool = nil
player.Backpack.ChildAdded:Connect(function(tool)
	if tool ~= lastTool and tool:IsA("Tool") then
		lastTool = nil
		table.insert(tools, tool)
	end
end)

player.Backpack.ChildRemoved:Connect(function(tool)
	if tool.Parent ~= player.Character and table.find(tools,tool) and tool:IsA("Tool") then
		table.remove(tools,table.find(tools,tool))
	end
end)

player.Character.ChildAdded:Connect(function(child)
	if child:IsA("Tool") then
		lastTool = tool
		updateUI(child)
	end
end)

player.Character.ChildRemoved:Connect(function(child)
	if child:IsA("Tool") then
		updateUI(nil)
	end
end)

I am sorry I am just really tired today.

1 Like

Its fine, but hey, atleast it worked now! although I wouldn’t able to unequip by switching to an empty slot. Still though, it worked!

Oh, that’s great. Please make sure to mark my post as the solution then. And I am sure you still could? Have you tried using this code snippet I provided?

local function equipTool(tool)
	player.Character:FindFirstChildOfClass("Humanoid"):UnequipTools()
	tool = player.Backpack:FindFirstChild(tool)
	if tool then
		player.Character:FindFirstChildOfClass("Humanoid"):EquipTool(tool)
	end
	updateUI(tool)
end

table.insert(tools,"")

local function nextTool()
	equippedToolIndex = equippedToolIndex % #tools + 1
end

local function previousTool()
	equippedToolIndex = (equippedToolIndex - 1) % #tools
	if equippedToolIndex == 0 then
		equippedToolIndex = #tools
	end
	equipTool(tostring(tools[equippedToolIndex]))
end

Oh ye, I tried this before, it kind of worked, the thing is the switchNext dint work, only the switchBack can

Oof, yeah I forgot to add equipTool() function in that function, just add that.

local function nextTool()
	equippedToolIndex = equippedToolIndex % #tools + 1
	equipTool(tostring(tools[equippedToolIndex]))
end

BUT I managed to fix it!

local function nextTool()
	equippedToolIndex = (equippedToolIndex + 1) % #tools
	if equippedToolIndex == 0 then
		equippedToolIndex = #tools
	end
	equipTool(tostring(tools[equippedToolIndex]))
end

All I did is copy the previousTool() function, but in an opposite way.

Yeah, no need for the

	if equippedToolIndex == 0 then
		equippedToolIndex = #tools
	end

Though as I only added it because I wasn’t able to find a formula for the previous iteration.

Glad I could help though!

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