Click detectors and tools

I think it is quite obvious for Click detector not to work when tool is equipped, but I ran into a bit different problem. Once I use a tool, it is practically removed from player’s inventory with :Destroy(), and after the tool is destroyed and theoretically unequipped ( may be actually not unequipped, considering the click detectors don’t work ), I am still unable to interact with click detectors… I was wondering if somebody had similar issue and if they found a way to deal with it.

I know I could use proximity prompt instead, in fact I am using it right now as a short term solution, but if there is an actual way to avoid it, I would love to hear it.

As of now, I had a theoretical idea, in which tool would not be deleted as soon as it is used, but instead it will check for boolean value, and if that value is true or false, then the tool will be deleted once tool:Unequipped() happens. Or just force unequip tool before deleting it.

3 Likes

Tried to recreate the issue on a Baseplate Template. Didn’t happen for me. What is your tool doing and how is it interacting with the mouse? I’m assuming theres something in the system of that tool that might be responsible, as for me the ClickDetector works as intended.

1 Like

I also wasn’t able to replicate this problem when I tested it on this place file:

ToolTest.rbxl (56.2 KB)

The tool is destroyed by the server after 2 seconds have passed since it’s been equipped

I also tried destroying the tool on the client-side, and using a script with RunContext set to Client for the ClickDetector, but the ClickDetector was able to register clicks afterwards


Just now, I’ve tested setting the tool’s parent to nil instead of destroying it, but once again ClickDetectors were able to detect clicks afterwards

If you wish. Basically here is a LocalScript in tool:

local ContextActionService = game:GetService("ContextActionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local tool = script.Parent

local players = game.Players
local player = players.LocalPlayer

local mouse = player:GetMouse()


local function SetStart(actionName, inputState)
	local target = mouse.Target
	if inputState == Enum.UserInputState.Begin and target.Name == "Node" and target:GetAttribute("Occupied") == false then
		ReplicatedStorage.Events.PutStartFlag:FireServer(target, tool)
	end
end

tool.Equipped:Connect(function()
	ContextActionService:BindAction("SetStart", SetStart, false, Enum.UserInputType.MouseButton1)
end)

tool.Unequipped:Connect(function()
	ContextActionService:UnbindAction("SetStart")
end)

And this is a server script in ServerScriptService connected by remote event to local script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

ReplicatedStorage.Events.PutStartFlag.OnServerEvent:Connect(function(player, target, tool)
	local flag = ReplicatedStorage.Assets.StartFlag:Clone()
	flag.Parent = target
	flag:MoveTo(target.Position + Vector3.new(0, 1, 0))
	
	target.Name = "Start"
	target.Color = Color3.fromRGB(240, 120, 60)
	
	player.Character.Humanoid:UnequipTools()
	tool:Destroy()
end)

The way script works, is that it sets a node that mouse is pointed at as start/finish. I can give more details if you wish. Sorry, for quite late reply.

I mean, that right there explains why clicks stop registering after you’ve destroyed the tool: You’re binding the left mouse button when the tool is equipped, and unbinding it after it’s unequipped. Since the Unequipped event is not triggered if a tool is destroyed, the action is never unbound. This explains why you’re not experiencing the problem if you force the player to unequip the tool before destroying it


By the way, tools have the Activated and Deactivated events, which are able to detect when a player clicks/unclicks their mouse. They seem to be worth using in your case, since you’re binding the SetStart function to the left mouse button, which is the same mouse button that’s detected by the Activated event. Activated will only trigger if the tool is equipped as well :slight_smile::+1:

I mean, yeah, that is right, but I do call an unequip event in server script when tool is used. Or it won’t work in the server script?

You can check to see if a player has a tool equipped on the server-side, by seeing if it’s currently parented to the player’s character:

local character = player.Character
if character == nil then return end

local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid == nil then return end

local tool = character:FindFirstChild("Set this to the name of your Tool")

if tool then
	humanoid:UnequipTools()
	tool:Destroy()
end

In your case, if you use my recommendation of using the Activated and Deactivated events, you won’t need to unequip the tool before destroying it

1 Like

Ok, I will try that when I get to my computer. Thanks for help.

1 Like

It did work. I still wonder, however, how would I achieve similar result if my tool used not just mouse as input, but other keys.

1 Like

This will detect when the tool is about to be destroyed, and unbind the action (needs to be a LocalScript in StarterCharacterScripts):

-- Needs to be a LocalScript in StarterCharacterScripts in-order to work!
local ContextActionService = game:GetService("ContextActionService")
local Players = game:GetService("Players")

local backpack = Players.LocalPlayer:WaitForChild("Backpack")
local tool = backpack:WaitForChild("Set this to the name of your Tool")


tool.Destroying:Connect(function()
	ContextActionService:UnbindAction("SetStart") -- Make sure that this matches the action name that you've used!
end)

I’ll try that too! Thanks!!! keystrokes

1 Like