Heya!
I am making a custom mouse for my game because I wanted to change all of its icons, but immediately ran into a problem.
I wanted to change the mouse (an image label)'s icon every time you hover over something clickable (ex: ClickDetectors, ImageButtons, TextButtons, ProximityPrompts, etc.) just like the normal one does.
Does anyone know how I could achieve this?
Anything like a property which tells me the real mouse’s current icon or the clickability of a GUI element / 3D object would really be helpful.
Just use the MouseEnter and MouseLeave event to detect the hovering over the GUI elemets and for 3D Object use mouse.Target and check if the object contains a ClickDetector etc.
That would work in theory, but I would have to create a listener for every single GUI object on the screen…
Also, I would have to make a list of all of the “clickable” objects since stuff like Frames and TextLabels aren’t clickable.
Not sure what you mean…
You could just use a for loop to loop through every Descendant of the PlayerGui and have the MouseEnter and MouseLeave event active for every object you allow it for.
For example:
Let’s say you have a ScreenGui with a LocalScript inside.
local plrGui = script.Parent.Parent
for _,v in pairs(plrGui:GetDescendants()) do
if v:IsA("TextButton") or v:IsA("ImageButton") then -- just put in every element you want this to happen
v.MouseEnter:Connect(function()
-- do what you want when mouse hovers over whitelisted element
end)
end
end
This would only become problematic if there would be new GUI elements added into plrGui midgame, but you could also solve this by checking if a child is added to plrGui.
Although it could work, there are 3 main problems with this:
If there are two overlapped buttons, if the mouse exits the first but is still inside the second then the icon will still change, since MouseLeave fires;
If the game has way too many GUI elements, then the amount of connections could lag the player.
Other than checking when an element is added, you would also have to check when it is removed to disconnect MouseEnter and MouseLeave, adding onto the amount of connections.
If you connect to InputChanged from UserInputService and use the GetGuiObjectsAtPosition method with the position from the InputObject given by InputChanged events for the mouse, you can list through all the GUIs at the mouse position. You can ignore any GUI objects that don’t inherit from GuiButton and ones that have Active or Interactable set to false. If there is a relevant GUI button, then you can set the new cursor. If there are absolutely no Active=true GUIs at that mouse position, you can proceed to raycast for a part with a ClickDetector. Do not raycast if there’s a GUI with Active set to true, even if it’s not a button.