Cursor icon not changing when over a click detector

I am trying to create a system where if a player’s mouse is over another player, the mouse’s icon will change to green. However while doing this, I encountered a strange bug.

Code found in the local script in StarterPlayerScripts:

local player = game:GetService("Players").LocalPlayer
local cursor = player:GetMouse()
cursor.Icon = "rbxassetid://10026327860" -- Default cursor

for i, v in pairs(workspace:GetDescendants()) do
	if v:IsA("ClickDetector") then
		if v.Name == "PlayerClickDetector" then
			v.MouseHoverEnter:Connect(function()
				cursor.Icon = "rbxassetid://10026330661" -- Changes the cursor to the active cursor
			end)
		end
	end
end

for i, v in pairs(workspace:GetDescendants()) do
	if v:IsA("ClickDetector") then
		if v.Name == "PlayerClickDetector" then
			v.MouseHoverLeave:Connect(function()
				cursor.Icon = "rbxassetid://10026327860" -- Changes the cursor back when it leaves the clickdetector
			end)
		end
	end
end

While testing with 2 players in studio, I found that the cursor would only change for one player.

Player 2’s view:
image
Player 1’s view:
image

This behavior is strange, because both players have the “PlayerClickDetector” clickdetector parented to their model, and when player 1 brings their cursor over a brick with the clickdetector, the cursor changes just fine.
image

Any thoughts?

I think maybe this is because it’s in a local script and you actually have to give everyone a clickdetector and a script that controls is server wide.

But in script way…

Function: when character added, add click detector to it

When you joined, run function without you.
When other joined after you, run function also.

The fact that there is an API on ClickDetector has a CursorIcon property is questioning why you chose to do it that way instead of the direct approach.

https://developer.roblox.com/en-us/api-reference/class/ClickDetector
https://developer.roblox.com/en-us/api-reference/property/ClickDetector/CursorIcon

I tried this, actually. It didn’t work with my custom cursor, which led me to trying what I showed above.
image
image

It’s simpler to just not use a ClickDetector. Since you already have the cursor icon handled from the LocalScript, can’t you just use that same script to handle clicks as well? This might not be possible, but this is something to consider, along with using RemoteEvents for replication.

This would involve me rewriting a lot of the current system I have so far. Would this really be necessary to fix this issue?

Well, not really. What I’ve done in the past is find a generic workaround (like every instance with a child named ClickDetector will have a separate script, that acts like a ClickDetector but really isn’t.)

Another thing I would do is look at the API documentation. What happens when you set the cursor of the ClickDetector to an empty string? What happens when you set it to the same ID as the cursor you’re looking for? There’s multiple things you can do.

Another solution is to get a whole different API that has similar functions. I might put some invisible SurfaceGUIs if I were you, but that’s just a hacky solution I wouldn’t go for.

Apparently setting the cursor icon has a higher priority than the ClickDetector? That’s super weird!

Instead, a long approach of scanning the mouse as it moves is possibly a solution. However, you have to account to the times when something moves in its position where the mouse doesn’t read. RunService.RenderStepped or something similar can work it out by rapidly checking the mouse’s “target” and so forth.

1 Like