Please Please help someone

So i want it to be like if my mouse is hovering over the mesh named SphereTemplate i cant place another there but my script doesnt seem to work its probably under somewhere in the mousebutton1down function

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local runService = game:GetService(“RunService”)
local replicatedStorage = game:GetService(“ReplicatedStorage”)
local cs = game:GetService(“CollectionService”)
local rs = game:GetService(“ReplicatedStorage”)
local PlaceCrop = rs:FindFirstChild(“PlaceCrop”)

local template = replicatedStorage:WaitForChild(“PlacementTemplate”)
template.Anchored = true
template.CanCollide = false
template.Parent = nil

local placementClone = nil
local currentTool = nil

local function isToolAllowed(tool: Tool)
return tool:HasTag(“Plantable”)
end

local function onToolEquipped(tool)
if not isToolAllowed(tool) then return end
currentTool = tool

if not placementClone then
	placementClone = template:Clone()
	placementClone.Anchored = true
	placementClone.CanCollide = false
	placementClone.Parent = workspace
end

tool.Unequipped:Connect(function()
	if placementClone then
		placementClone:Destroy()
		placementClone = nil
	end
	currentTool = nil
end)

end

local function monitorTools(character)
for _, child in ipairs(character:GetChildren()) do
if child:IsA(“Tool”) then
child.Equipped:Connect(function()
onToolEquipped(child)
end)
end
end

character.ChildAdded:Connect(function(child)
	if child:IsA("Tool") then
		child.Equipped:Connect(function()
			onToolEquipped(child)
		end)
	end
end)

end

if player.Character then
monitorTools(player.Character)
end
player.CharacterAdded:Connect(monitorTools)

local function updatePlacementPosition()
if not placementClone then return end

local camera = workspace.CurrentCamera
if not camera then return end

local origin = camera.CFrame.Position
local direction = (mouse.Hit.Position - origin).Unit * 500

local rayParams = RaycastParams.new()
rayParams.FilterDescendantsInstances = {cs:GetTagged("garden")}
rayParams.FilterType = Enum.RaycastFilterType.Include

local result = workspace:Raycast(origin, direction, rayParams)

if result and result.Instance then
	local surfacePos = result.Position + Vector3.new(0, placementClone.Size.Y / 2, 0)
	placementClone.Position = surfacePos
end

end

runService.RenderStepped:Connect(updatePlacementPosition)

mouse.Button1Down:Connect(function()
if not placementClone or not currentTool then return end

local camera = workspace.CurrentCamera
if not camera then return end

local mousePos = mouse.Hit.Position
local origin = camera.CFrame.Position
local direction = (mousePos - origin).Unit * 1000

local rayParams = RaycastParams.new()
rayParams.FilterDescendantsInstances = {workspace}
rayParams.FilterType = Enum.RaycastFilterType.Include
rayParams.IgnoreWater = true

local result = workspace:Raycast(origin, direction, rayParams)

-- Make sure spheres exist
local spheresFolder = workspace:FindFirstChild("spheres")
if not spheresFolder then
	warn("Spheres folder not found.")
	return
end

-- Check if ANY sphere was hit directly by the mouse
local mouseTarget = mouse.Target
if mouseTarget and mouseTarget:IsDescendantOf(spheresFolder) then
	warn("Cannot place crop directly on a sphere.")
	return
end

-- ✅ Passes all checks, place the crop
if PlaceCrop then
	PlaceCrop:FireServer(currentTool.Name, placementClone.Position)
end

end)Preformatted text

Hi

Okey so first of all, any tool added to the player character model will be equiped, so you don’t have to listen to the equiped event when a tool is added to your character.

Second, you are connecting to Unequiped signal each time you equip a tool which can consume more memory and decrease performance, you just have to connect to that signal only one time when the tool equiped.

Third, any tool without a handle will not trigger the Equiped and Unequiped RBXSignal. If your tool doesn’t have a handle you should listen when it’s parent changed then, if the parent is the player character you know the tool is equiped, otherwise the tool unquiped.

Last, I really don’t know what the issue is because you didn’t specify it clearly but make sure there is PlaceCrop value (or any other instance) in the replicated storage.

Here is an optimized version of your script:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local runService = game:GetService("RunService")
local replicatedStorage = game:GetService("ReplicatedStorage")
local cs = game:GetService("CollectionService")
local rs = game:GetService("ReplicatedStorage")
local PlaceCrop = rs:FindFirstChild("PlaceCrop")

local template = replicatedStorage:WaitForChild("PlacementTemplate")
template.Anchored = true
template.CanCollide = false
template.Parent = nil

local placementClone = nil
local currentTool = nil

local function isToolAllowed(tool: Tool)
	return tool:HasTag("Plantable")
end

local function onToolEquipped(tool)
	if not isToolAllowed(tool) then return end
	currentTool = tool

	if not placementClone then
		placementClone = template:Clone()
		placementClone.Anchored = true
		placementClone.CanCollide = false
		placementClone.Parent = workspace
	end

	tool:GetPropertyChangedSignal("Parent"):Once(function()
		if tool.Parent ~= player.Character then
			if placementClone then
				placementClone:Destroy()
				placementClone = nil
			end
			currentTool = nil
		end
	end)
end

local function monitorTools(character)
	for _, child in ipairs(character:GetChildren()) do
		if child:IsA("Tool") then
			onToolEquipped(child)
		end
	end

	character.ChildAdded:Connect(function(child)
		if child:IsA("Tool") then
			onToolEquipped(child)
		end
	end)

end

if player.Character then
	monitorTools(player.Character)
end
player.CharacterAdded:Connect(monitorTools)

local function updatePlacementPosition()
	if not placementClone then return end

	local camera = workspace.CurrentCamera
	if not camera then return end

	local origin = camera.CFrame.Position
	local direction = (mouse.Hit.Position - origin).Unit * 500

	local rayParams = RaycastParams.new()
	rayParams.FilterDescendantsInstances = {cs:GetTagged("garden")}
	rayParams.FilterType = Enum.RaycastFilterType.Include

	local result = workspace:Raycast(origin, direction, rayParams)

	if result and result.Instance then
		local surfacePos = result.Position + Vector3.new(0, placementClone.Size.Y / 2, 0)
		placementClone.Position = surfacePos
	end
end

runService.RenderStepped:Connect(updatePlacementPosition)

mouse.Button1Down:Connect(function()
	if not placementClone or not currentTool then return end

	local camera = workspace.CurrentCamera
	if not camera then return end

	local mousePos = mouse.Hit.Position
	local origin = camera.CFrame.Position
	local direction = (mousePos - origin).Unit * 1000

	local rayParams = RaycastParams.new()
	rayParams.FilterDescendantsInstances = {workspace}
	rayParams.FilterType = Enum.RaycastFilterType.Include
	rayParams.IgnoreWater = true

	local result = workspace:Raycast(origin, direction, rayParams)

	-- Make sure spheres exist
	local spheresFolder = workspace:FindFirstChild("spheres")
	if not spheresFolder then
		warn("Spheres folder not found.")
		return
	end

	-- Check if ANY sphere was hit directly by the mouse
	local mouseTarget = mouse.Target
	if mouseTarget and mouseTarget:IsDescendantOf(spheresFolder) then
		warn("Cannot place crop directly on a sphere.")
		return
	end

	-- ✅ Passes all checks, place the crop
	if PlaceCrop then
		PlaceCrop:FireServer(currentTool.Name, placementClone.Position)
	end
end)