I cant find the problem in my script!

Hello developers, I have a big problem.
I made my own inventory and in my script when I press the equip button it equips the plr with the correct tool then the button change to orange and the text to “Unequip”.
But here’s the problem, when the plr press the unequip button, it invoke the equip function and not the unequip function .

I think the problem is this part of my script :

else -- plr has not equipped this tool
						---- Set the equipButton.Text to "Equip" and the color to Light Green ----
						equipButton.Text = "Equip"
						equipButton.BackgroundColor3 = Color3.fromRGB(0, 193, 0)
						equipButton.BorderColor3 = Color3.fromRGB(0, 193, 0)
						---- Making some checks to call the server to equip the tool ----
						local debounce = false -- Creating a debounce to avoir the server to be overloaded
						---- This is the clicked function to Invoke the EquipFunction ----
						equipButton.MouseButton1Click:Connect(function()
							if debounce == false then
								debounce = true -- The server can not be spam anymore (until this function has run)
								---- Set a new variable to know if it works (result) and Invoke the EquipFunction
								local result = game.ReplicatedStorage.Remotes.EquipTool:InvokeServer(tool.Name) -- Give the argument "tool.Name" to the server
								---- If it worked (result = true) : Change the text color and the text to Orange and to "Unequip"
								if result == true then
									equipButton.Text = "Unequip"
									equipButton.BackgroundColor3 = Color3.fromRGB(165, 40, 9)
									equipButton.BorderColor3 = Color3.fromRGB(126, 25, 0)
								end
								---- Wait 0.5 second and set the debounce to false, the server can be called again ----
								wait(.5)
								debounce = false
							end
						end)
					end
					module.openIFrame()
					open.Value = true
				else -- IFrame is opened 
					---- Close the IFrame ----
					module.closeIFrame()
					wait()
					---- Set all items informations into IFrame stuff (Name, Rarity, Desc, EquippedStatus) ----
					descPart.Text = tool:FindFirstChild("Description").Value
					ItemName.Text = tool.Name
					---- Set the text color to the rarity color ----
					local rarity = tool:FindFirstChild("Rarity").Value
					if rarity == "Common" then
						ItemName.TextColor3 = Color3.fromRGB(56, 56, 56)
					elseif rarity == "Uncommon" then
						ItemName.TextColor3 = Color3.fromRGB(95, 180, 76)
					elseif rarity == "Rare" then
						ItemName.TextColor3 = Color3.fromRGB(18, 59, 239)
					elseif rarity == "Epic" then
						ItemName.TextColor3 = Color3.fromRGB(126, 0, 189)
					elseif rarity == "Typical" then
						ItemName.TextColor3 = Color3.fromRGB(37, 185, 175)
					elseif rarity == "Legendary" then
						ItemName.TextColor3 = Color3.fromRGB(225, 49, 25)
					elseif rarity == "Mythic" then
						ItemName.TextColor3 = Color3.fromRGB(19, 255, 3)
					elseif rarity == "Special" then
						ItemName.TextColor3 = Color3.fromRGB(22, 2, 83)
					else
						---- If any rarity is found then ----
						ItemName.Text = "There was an error!"
					end
					---- Clear the IFrame DisplayItem ----
					for _, v in pairs(DisplayItem.ViewportFrame:GetChildren()) do
						if v then
							v:Destroy()
						end
					end
					---- Set the right object to display into the VPF inside of the IFrame ----
					local object2 = tool:Clone()
					object2.Parent = DisplayItem.ViewportFrame
					---- Create the new camera ----
					local camera = Instance.new("Camera")
					camera.CFrame = CFrame.new(object2.Handle.Position + (object2.Handle.CFrame.lookVector*5),object2.Handle.Position)
					camera.Parent = DisplayItem.ViewportFrame
					DisplayItem.ViewportFrame.CurrentCamera = camera
					---- Set up the EquipButton.Text and EquipButton.TextColor3 to the right color ----
					if plr.Character:FindFirstChild(tool.Name) then -- Plr has this tool Equipped
						---- Set the equipButton.Text to "Unequip" and the color to Orange ----
						equipButton.Text = "Unequip"
						equipButton.BackgroundColor3 = Color3.fromRGB(165, 40, 9)
						equipButton.BorderColor3 = Color3.fromRGB(126, 25, 0)
						---- Making some checks  to call the server to unequip the equipped tool ----
						local debounce = false -- Creating a debounce to avoid the server to be overloaded
						---- This is the clicked function to Invoke the UnequipFunction ----
						equipButton.MouseButton1Click:Connect(function()
							
							if debounce == false then
								debounce = true -- The server can not be spam anymore (until this function has run)
								---- Set a new variable to know if it works (result) and Invoke the Unequip function ----
								local result = game.ReplicatedStorage.Remotes.UnequipTool:InvokeServer(tool.Name) -- Give the argument "tool.Name" to the server 
								---- If it worked (result = true) :Change the text color and the text to Light Green and to "Equip" ----
								if result == true then
									equipButton.Text = "Equip"
									equipButton.BackgroundColor3 = Color3.fromRGB(0, 193, 0)
									equipButton.BorderColor3 = Color3.fromRGB(0, 193, 0)
								end
								wait(.5)
								debounce = false
							end
						end)
					else -- plr has not equipped this tool
						---- Set the equipButton.Text to "Equip" and the color to Light Green ----
						equipButton.Text = "Equip"
						equipButton.BackgroundColor3 = Color3.fromRGB(0, 193, 0)
						equipButton.BorderColor3 = Color3.fromRGB(0, 193, 0)
						---- Making some checks to call the server to equip the tool ----
						local debounce = false -- Creating a debounce to avoir the server to be overloaded
						---- This is the clicked function to Invoke the EquipFunction ----
						equipButton.MouseButton1Click:Connect(function()
							if debounce == false then
								debounce = true -- The server can not be spam anymore (until this function has run)
								---- Set a new variable to know if it works (result) and Invoke the EquipFunction
								local result = game.ReplicatedStorage.Remotes.EquipTool:InvokeServer(tool.Name) -- Give the argument "tool.Name" to the server
								---- If it worked (result = true) : Change the text color and the text to Orange and to "Unequip"
								if result == true then
									equipButton.Text = "Unequip"
									equipButton.BackgroundColor3 = Color3.fromRGB(165, 40, 9)
									equipButton.BorderColor3 = Color3.fromRGB(126, 25, 0)
								end
								---- Wait 0.5 second and set the debounce to false, the server can be called again ----
								wait(.5)
								debounce = false
							end
						end)
					end
					wait(1)
					module.openIFrame()
					open.Value = true
				end
			end
		end)
	end
end

This is the server script to equip and unequip tools :

---- This function will run when the client Invoke the server ----
game.ReplicatedStorage.Remotes.EquipTool.OnServerInvoke = function(plr,toolName) -- Client has invoke this function
	---- Set a variable to our tool ----
	local tool = game.ReplicatedStorage.Tools:FindFirstChild(toolName)
	---- Make some checks to avoid problems ----
	if tool then
		---- Set a variable for the humanoid(hum) ----
		local hum = plr.Character:FindFirstChild("Humanoid")
		if hum then
			---- Equip the tool ----
			hum:EquipTool(tool)
			print("Equip")
			---- If it works, return true
			return true
			---- Other issues = result = false
		else return false
		end
	else return false
	end
end

---- This function will run when the client invoke the server ----
game.ReplicatedStorage.Remotes.UnequipTool.OnServerInvoke = function(plr,toolName) -- Client has invoke this function
	print("Function unequip")
	---- Looking for the tool and link it to a variable ----
	local tool = plr.Character:FindFirstChild(toolName)
	---- Check if there is the hat ----
	if tool then
		---- Find the humanoid and link it to a variable (hum) ----
		local hum = plr.Character:FindFIrstChild("Humanoid")
		if hum then
			---- Unequip all plr's tools ----
			hum:UnequipTools()
			print("Unequip")
		end
	end
end

and this is the entire script if you need it :

---- Variables ----
local Inventory = script.Parent -- Local ScreenGui
local frame = Inventory:WaitForChild("Frame") -- Local MainFrame
local iFrame = frame:WaitForChild("IFrame") -- Local IFrame
local SFrame = frame:WaitForChild("ScrollingFrame") -- Local ScrollingFrame
local background = frame:WaitForChild("Background") -- Local MainBackgroundImage
local template = SFrame:WaitForChild("Template") -- Local Template
local descPart = iFrame:WaitForChild("DescriptionBox") -- Local DescriptionBox
local DisplayItem = iFrame:WaitForChild("DisplayItem") -- Local ViewportFrame (Into the IFrame)
local ItemName  = iFrame:WaitForChild("ItemName") -- ItemName (Into the IFrame)
local status = Inventory:WaitForChild("Status") -- Main BoolValue to manage the entire MainFrameGui
local open = iFrame:WaitForChild("Open") -- Local Open BoolValue to manage the IFrame
local equipButton = iFrame:WaitForChild("EquipButton") -- Local EquipButton
---- Require module ----
local module = require(game.StarterGui.GuiHolder)  -- Set your module to find back your GuiTweening
---- Onglets ----
local TOnglet = frame:WaitForChild("ToolIcon")
local HOnglet = frame:WaitForChild("HatsIcon")
local POnglet = frame:WaitForChild("PetIcon")

------------ Define Tools's function ------------

local function toolsDisplay()
	---- Destroy all current templates ----
	for _, temp in pairs(SFrame:GetChildren()) do
		if temp:IsA("TextButton") then
			if temp.Name ~= "Template" then
				temp:Destroy()
			end
		end
	end
	---- Define plr ----
	local plr = game.Players.LocalPlayer
	---- Create a new template for each tool ----
	for _, tool in pairs(plr.Inventory.ToolsInventory:GetChildren()) do
		local newTemplate = template:Clone()
		newTemplate.Name = tool.Name
		newTemplate.ObjectName.Text = tool.Name
		newTemplate.Visible = true
		newTemplate.Parent = SFrame
		---- Set up the ViewportFrame ----
		-- Add the object into the VPF --
		local object = tool:Clone()
		object.Parent = newTemplate.ViewportFrame
		-- Add the camera into the VPF --
		local camera = Instance.new("Camera")
		camera.CFrame = CFrame.new(object.Handle.Position + (object.Handle.CFrame.lookVector*5),object.Handle.Position) -- We can change the camera view here --
		camera.Parent = newTemplate.ViewportFrame
		newTemplate.ViewportFrame.CurrentCamera = camera
		---- Create an event to open the IFrame with the tool informations when its template is clicked ----
		newTemplate.MouseButton1Click:Connect(function()
			---- Checking informations to act correctly, step by step ----
			if open then
				if open.Value == false then -- IFrame is closed
					---- Set all items informations into IFrame stuff (Name, Rarity, Desc, EquippedStatus) ----
					descPart.Text = tool:FindFirstChild("Description").Value
					ItemName.Text = tool.Name
					---- Set the text color to the rarity color ----
					local rarity = tool:FindFirstChild("Rarity").Value
					if rarity == "Common" then
						ItemName.TextColor3 = Color3.fromRGB(56, 56, 56)
					elseif rarity == "Uncommon" then
						ItemName.TextColor3 = Color3.fromRGB(95, 180, 76)
					elseif rarity == "Rare" then
						ItemName.TextColor3 = Color3.fromRGB(18, 59, 239)
					elseif rarity == "Epic" then
						ItemName.TextColor3 = Color3.fromRGB(126, 0, 189)
					elseif rarity == "Typical" then
						ItemName.TextColor3 = Color3.fromRGB(37, 185, 175)
					elseif rarity == "Legendary" then
						ItemName.TextColor3 = Color3.fromRGB(225, 49, 25)
					elseif rarity == "Mythic" then
						ItemName.TextColor3 = Color3.fromRGB(19, 255, 3)
					elseif rarity == "Special" then
						ItemName.TextColor3 = Color3.fromRGB(22, 2, 83)
					else
						---- If any rarity is found then ----
						ItemName.Text = "There was an error!"
					end
					---- Clear the IFrame DisplayItem ----
					for _, v in pairs(DisplayItem.ViewportFrame:GetChildren()) do
						if v then
							v:Destroy()
						end
					end
					---- Set the right object to display into the VPF inside of the IFrame ----
					local object2 = tool:Clone()
					object2.Parent = DisplayItem.ViewportFrame
					---- Create the new camera ----
					local camera = Instance.new("Camera")
					camera.CFrame = CFrame.new(object2.Handle.Position + (object2.Handle.CFrame.lookVector*5),object2.Handle.Position)
					camera.Parent = DisplayItem.ViewportFrame
					DisplayItem.ViewportFrame.CurrentCamera = camera
					---- Set up the EquipButton.Text and EquipButton.TextColor3 to the right color ----
					if plr.Character:FindFirstChild(tool.Name) then -- Plr has this tool Equipped
						---- Set the equipButton.Text to "Unequip" and the color to Orange ----
						equipButton.Text = "Unequip"
						equipButton.BackgroundColor3 = Color3.fromRGB(165, 40, 9)
						equipButton.BorderColor3 = Color3.fromRGB(126, 25, 0)
						---- Making some checks  to call the server to unequip the equipped tool ----
						local debounce = false -- Creating a debounce to avoid the server to be overloaded
						---- This is the clicked function to Invoke the UnequipFunction ----
						equipButton.MouseButton1Click:Connect(function()
							if debounce == false then
								debounce = true -- The server can not be spam anymore (until this function has run)
								---- Set a new variable to know if it works (result) and Invoke the Unequip function ----
								local result = game.ReplicatedStorage.Remotes.UnequipTool:InvokeServer(tool.Name) -- Give the argument "tool.Name" to the server 
								---- If it worked (result = true) :Change the text color and the text to Light Green and to "Equip" ----
								if result == true then
									equipButton.Text = "Equip"
									equipButton.BackgroundColor3 = Color3.fromRGB(0, 193, 0)
									equipButton.BorderColor3 = Color3.fromRGB(0, 193, 0)
								end
								wait(.5)
								debounce = false
							end
						end)
					else -- plr has not equipped this tool
						---- Set the equipButton.Text to "Equip" and the color to Light Green ----
						equipButton.Text = "Equip"
						equipButton.BackgroundColor3 = Color3.fromRGB(0, 193, 0)
						equipButton.BorderColor3 = Color3.fromRGB(0, 193, 0)
						---- Making some checks to call the server to equip the tool ----
						local debounce = false -- Creating a debounce to avoir the server to be overloaded
						---- This is the clicked function to Invoke the EquipFunction ----
						equipButton.MouseButton1Click:Connect(function()
							if debounce == false then
								debounce = true -- The server can not be spam anymore (until this function has run)
								---- Set a new variable to know if it works (result) and Invoke the EquipFunction
								local result = game.ReplicatedStorage.Remotes.EquipTool:InvokeServer(tool.Name) -- Give the argument "tool.Name" to the server
								---- If it worked (result = true) : Change the text color and the text to Orange and to "Unequip"
								if result == true then
									equipButton.Text = "Unequip"
									equipButton.BackgroundColor3 = Color3.fromRGB(165, 40, 9)
									equipButton.BorderColor3 = Color3.fromRGB(126, 25, 0)
								end
								---- Wait 0.5 second and set the debounce to false, the server can be called again ----
								wait(.5)
								debounce = false
							end
						end)
					end
					module.openIFrame()
					open.Value = true
				else -- IFrame is opened 
					---- Close the IFrame ----
					module.closeIFrame()
					wait()
					---- Set all items informations into IFrame stuff (Name, Rarity, Desc, EquippedStatus) ----
					descPart.Text = tool:FindFirstChild("Description").Value
					ItemName.Text = tool.Name
					---- Set the text color to the rarity color ----
					local rarity = tool:FindFirstChild("Rarity").Value
					if rarity == "Common" then
						ItemName.TextColor3 = Color3.fromRGB(56, 56, 56)
					elseif rarity == "Uncommon" then
						ItemName.TextColor3 = Color3.fromRGB(95, 180, 76)
					elseif rarity == "Rare" then
						ItemName.TextColor3 = Color3.fromRGB(18, 59, 239)
					elseif rarity == "Epic" then
						ItemName.TextColor3 = Color3.fromRGB(126, 0, 189)
					elseif rarity == "Typical" then
						ItemName.TextColor3 = Color3.fromRGB(37, 185, 175)
					elseif rarity == "Legendary" then
						ItemName.TextColor3 = Color3.fromRGB(225, 49, 25)
					elseif rarity == "Mythic" then
						ItemName.TextColor3 = Color3.fromRGB(19, 255, 3)
					elseif rarity == "Special" then
						ItemName.TextColor3 = Color3.fromRGB(22, 2, 83)
					else
						---- If any rarity is found then ----
						ItemName.Text = "There was an error!"
					end
					---- Clear the IFrame DisplayItem ----
					for _, v in pairs(DisplayItem.ViewportFrame:GetChildren()) do
						if v then
							v:Destroy()
						end
					end
					---- Set the right object to display into the VPF inside of the IFrame ----
					local object2 = tool:Clone()
					object2.Parent = DisplayItem.ViewportFrame
					---- Create the new camera ----
					local camera = Instance.new("Camera")
					camera.CFrame = CFrame.new(object2.Handle.Position + (object2.Handle.CFrame.lookVector*5),object2.Handle.Position)
					camera.Parent = DisplayItem.ViewportFrame
					DisplayItem.ViewportFrame.CurrentCamera = camera
					---- Set up the EquipButton.Text and EquipButton.TextColor3 to the right color ----
					if plr.Character:FindFirstChild(tool.Name) then -- Plr has this tool Equipped
						---- Set the equipButton.Text to "Unequip" and the color to Orange ----
						equipButton.Text = "Unequip"
						equipButton.BackgroundColor3 = Color3.fromRGB(165, 40, 9)
						equipButton.BorderColor3 = Color3.fromRGB(126, 25, 0)
						---- Making some checks  to call the server to unequip the equipped tool ----
						local debounce = false -- Creating a debounce to avoid the server to be overloaded
						---- This is the clicked function to Invoke the UnequipFunction ----
						equipButton.MouseButton1Click:Connect(function()
							
							if debounce == false then
								debounce = true -- The server can not be spam anymore (until this function has run)
								---- Set a new variable to know if it works (result) and Invoke the Unequip function ----
								local result = game.ReplicatedStorage.Remotes.UnequipTool:InvokeServer(tool.Name) -- Give the argument "tool.Name" to the server 
								---- If it worked (result = true) :Change the text color and the text to Light Green and to "Equip" ----
								if result == true then
									equipButton.Text = "Equip"
									equipButton.BackgroundColor3 = Color3.fromRGB(0, 193, 0)
									equipButton.BorderColor3 = Color3.fromRGB(0, 193, 0)
								end
								wait(.5)
								debounce = false
							end
						end)
					else -- plr has not equipped this tool
						---- Set the equipButton.Text to "Equip" and the color to Light Green ----
						equipButton.Text = "Equip"
						equipButton.BackgroundColor3 = Color3.fromRGB(0, 193, 0)
						equipButton.BorderColor3 = Color3.fromRGB(0, 193, 0)
						---- Making some checks to call the server to equip the tool ----
						local debounce = false -- Creating a debounce to avoir the server to be overloaded
						---- This is the clicked function to Invoke the EquipFunction ----
						equipButton.MouseButton1Click:Connect(function()
							if debounce == false then
								debounce = true -- The server can not be spam anymore (until this function has run)
								---- Set a new variable to know if it works (result) and Invoke the EquipFunction
								local result = game.ReplicatedStorage.Remotes.EquipTool:InvokeServer(tool.Name) -- Give the argument "tool.Name" to the server
								---- If it worked (result = true) : Change the text color and the text to Orange and to "Unequip"
								if result == true then
									equipButton.Text = "Unequip"
									equipButton.BackgroundColor3 = Color3.fromRGB(165, 40, 9)
									equipButton.BorderColor3 = Color3.fromRGB(126, 25, 0)
								end
								---- Wait 0.5 second and set the debounce to false, the server can be called again ----
								wait(.5)
								debounce = false
							end
						end)
					end
					wait(1)
					module.openIFrame()
					open.Value = true
				end
			end
		end)
	end
end

---- This will run when we close or open the inventory ----
status:GetPropertyChangedSignal("Value"):Connect(function()
	---- If the inventory is closed and the onglets are closed ----
	if status.Value == true and TOnglet:FindFirstChild("Open").Value == false and HOnglet:FindFirstChild("Open").Value == false and POnglet:FindFirstChild("Open").Value == false then 
		---- Run the function ----
		toolsDisplay()
		---- Set the Onglet's background transparency to 0 to show the light green background to show this is the opened onglet and set the open value to true  ----
		TOnglet:FindFirstChild("Open").Value = true
		TOnglet.BackgroundTransparency = 0
	else
		---- Debuger : Avoid any errors by reseting all the Onglet's "Open"s to false and the background Transparency to 1
		TOnglet.Open.Value = false
		HOnglet.Open.Value = false
		POnglet.Open.Value = false
		TOnglet.BackgroundTransparency = 1
		HOnglet.BackgroundTransparency = 1
		POnglet.BackgroundTransparency = 1
	end
end)

---- This will run when we press the ToolsOnglet ----
TOnglet.MouseButton1Click:Connect(function()
	local open = TOnglet.Open
	if not open.Value then
		---- First thing first, close the IFrame ----
		module.closeIFrame()
		wait(.5)
		---- Run the function ----
		toolsDisplay()
		---- Show it is opened ----
		open.Value = true
		TOnglet.BackgroundTransparency = 0
		---- Reset other onglets ----
		HOnglet.Open.Value = false
		POnglet.Open.Value = false
		HOnglet.BackgroundTransparency = 1
		POnglet.BackgroundTransparency = 1
	end
end)
1 Like

I’ll be honest I did not trace through all your code. But I notice you didn’t have the unequip function as part of the same clicked event as the equip function. Why not do it all in one?

Example:

local equipped = false
equipButton.MouseButton1Click:Connect(function()
    if not(equipped)then
        --Equip stuff code
        equipped = true
    else
        --unequipped stuff
        equipped = false
    end
end)

What I did is change the Text of the EquipButton and the color and when the button is clicked, it invoke the equip or unequip function from a local script.

And if the equipButton text is “Unequip” it invoke unequip function and else it invoke equip function so have I to change this?

I’m really trying to avoid tracing the entire flow of the script lol. I’m sorry. I’m guessing though that there is a problem with connecting the event. So you check at one point if the player has the tool equipped or not and then you create the click event each time based on that. I feel like you should have a single function that handles the clicking of the button. It would reduce the code redundancy and clean it up a bit for readability. Then whenever that button is clicked it can check if the tool is equipped or not and handle things accordingly. Do the connection to that function 1 time as soon as the button becomes available to the user.

Have I to equip or unequip the player by the server to avoid exploit or I can let the client equip the tool?
Thx you for your help !

Should I put a BoolValue (“Equipped”) Into all tools or is it working if I put the equipped variable into the script like you did upper ?

If you have different tools, then yea the “equipped” flag would be in each tool as a local variable to the whole script.