Script Doesn't detect mouse click while holding a tool

hello!

In my script, It says if i click a part it detects if I am holding tool, if so it will print a statement and delete the tool. However when I hold out the tool and click the part, it does not print or do anything.
But, if I click the part without holding the tool it says,

No tool found.

Also when I equip the tool it doesn’t print out

Tool equipped

Any solutions?

local part = script.Parent
local ClickDet = part:FindFirstChild("ClickDetector")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

if ClickDet then
	ClickDet.MouseClick:Connect(function(player)
		local tool = player.Backpack:FindFirstChildWhichIsA("Tool")
		if tool and tool:IsA("Tool") then
			tool.Equipped:Connect(function()
				print("Tool equipped")
			end)
			print("Tool found")
			tool:Destroy()
		else
			print("No tool found")
		end
	end)
else
	warn("ClickDetector not found")
end

tool.Equipped only fires when you equip the tool, not to detect if its equipped or not, instead, do player.Character:FindFirstChildOfClass("Tool")

1 Like

Where do i put that in my script?

replace this whole thing with:

  local tool = player.Backpack:FindFirstChildOfClass("Tool")
		if tool then
				print("Tool equipped")

It didn’t print out the print statement.

Here’s my script:

local part = script.Parent
local ClickDet = part:FindFirstChild("ClickDetector")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

if ClickDet then
	ClickDet.MouseClick:Connect(function(player)
		local tool = player.Backpack:FindFirstChildOfClass("Tool")
		if tool then
			print("Tool equipped")
			print("Tool found")
			tool:Destroy()
		else
			print("No tool found")
		end
	end)
else
	warn("ClickDetector not found")
end

You need to check both the player’s Backpack and Character for the tool.

local part = script.Parent
local ClickDet = part:FindFirstChild("ClickDetector")

if ClickDet then
    ClickDet.MouseClick:Connect(function(player)
        -- Check both Backpack and Character for a tool
        local tool = player.Backpack:FindFirstChildOfClass("Tool") or player.Character:FindFirstChildOfClass("Tool")
        if tool then
            print("Tool equipped")
            print("Tool found")
            tool:Destroy()
        else
            print("No tool found")
        end
    end)
else
    warn("ClickDetector not found")
end

1 Like

Nope, still doesn’t print out the statemets. Also I do not start the game with the tool.

ClickDetectors don’t work when you are holding a tool.
Use tool.Activated to detect when you click with a tool equiped.

Where do I put that in the script?

I would use proximity prompts instead because you can actually interact with them while holding a tool, instead of ClickDetectors.

Ok I will try that.

Character Requirement.

Why does it say “Recieved Remote” when i join the game?

image_2025-02-09_153107679

ServerScript:

local part = script.Parent
local ProxPrompt = part:FindFirstChild("ProximityPrompt")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

game.Players.PlayerAdded:Connect(function(player)
	local Backpack = player.Backpack
	if ProxPrompt.Triggered then
		ReplicatedStorage.SellRemote:FireClient(player)
		
	end
end)

Local Script:

SellRemote.OnClientEvent:Connect(function()
	print("Recieved Remote")
    local equippedTool = character:FindFirstChildWhichIsA("Tool")
    if equippedTool then
        equippedTool:Destroy()
    end
end)

You need to do

ProxPrompt.Triggered:Connect(function(player)
  ReplicatedStorage.SellRemote:FireClient(player)
end)

Instead of playeradded

1 Like

I also want to give the player credits when it destroys the tool (recieved the remote)
I have tried to call the leaderstats but this error pops up:
15:37:27.031 Workspace.planeboy2021.SellItem:50: attempt to index nil with ‘leaderstats’ - Client - SellItem:50

Local script:

SellRemote.OnClientEvent:Connect(function(player)
	print("Recieved Remote")
	local equippedTool = character:FindFirstChildWhichIsA("Tool")
	local Credits = player.leaderstats.Credits
	if Credits then
		print("True")
	end
    if equippedTool then
		equippedTool:Destroy()
		
    end
end)


And yes i have already created the datastore for the leaderstats

I told you that this is problematic

Wait i realised that i need to change the credits in the server.

If the proximity prompt script is a serverside script you can just skip the firing of the event an put the code inside of there. You are firing a player but you are not sending the players with it, also you would only be destroying the tool client sided and adding credits client sided. Thus that is why you should have it in the serverside script with the proximity prompt.
What you are doing rn is basically.
Server sends nil to player → player puts nil into the player var → you can’t get leaderstats from nil aka nil.leaderstats

Ok I have set the leaderstat in the server using return with a remote function, and now it works!!!

Server Script:

local part = script.Parent
local ProxPrompt = part:FindFirstChild("ProximityPrompt")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

ProxPrompt.Triggered:Connect(function(player)
	local remote = ReplicatedStorage.SellRemote:InvokeClient(player)
	local leaderstats = player.leaderstats
	local Credits = leaderstats.Credits
	
	if remote then
		print(remote)
		Credits.Value = Credits.Value + remote
	end
	
end)

Local Script:

local Items = {
    ["Newspaper"] = 3,
    ["Rat"] = 2,
    ["Broken Furniture"] = 70,
    ["Toy"] = 8,
    ["Bottle"] = 3,
    ["Shoes"] = 13,
    ["Monitor"] = 85,
    ["Clothes"] = 10,
    ["Scrap Metal"] = 2,
    ["Cardboard"] = 4,
    ["Book"] = 4,
    ["Plastic Container"] = 7,
    ["Food Scraps"] = 13,
    ["Hammer"] = 30,
    ["Can"] = 3,
    ["Magazines"] = 12,
    ["Dishes"] = 27,
    ["Batteries"] = 25,
    ["Desk"] = 115,
    ["Chair"] = 43,
    ["Keyboard"] = 58,
    ["Lights"] = 43,
    ["PC"] = 468,
    ["Fridge"] = 324,
    ["Microwave"] = 286,
    ["Paint Brush"] = 11,
    ["Paint Can"] = 7
}

local player = game.Players.LocalPlayer
local RepStorage = game:GetService("ReplicatedStorage")
local SellRemote = RepStorage.SellRemote
local character = player.Character or player.CharacterAdded:Wait()

local Price = 0

character.ChildAdded:Connect(function(newChild)
	if not newChild:IsA("Tool") then return end

	local value = Items[newChild.Name]
	if value then
		print(newChild.Name .. " is worth: " .. value)
		Price = value
	else
		print(newChild.Name .. " not found in table")
	end
end)

SellRemote.OnClientInvoke = function(player)
	print("Recieved Remote")
	local equippedTool = character:FindFirstChildWhichIsA("Tool")
	
    if equippedTool then
		equippedTool:Destroy()
		return Price

	end
end

It would be better if you removed the tool server sided too.
And you could use a module script to store the prices.

The client should have zero involvement in your system