Is it possible to find out which GUI elements are under the mouse cursor?
This is especially necessary when a bunch of ScreenGui with a bunch of Frames with different elements.
For example, at the moment, it is not clear why the last button from a bunch of script-created ones does not work? The last thought remains - it is blocked by something …
Well there’s GetGuiObjectsAtPosition, but unfortunately there’s no built in way to determine the order of GuiObjects, so if you want to also find out which one is on top then you’ll have to write a custom function for that. It’s surprisingly complicated if you want it to work across all ScreenGuis in a game which may have mixed ZIndexBehaviors, but if you limit it to only one ScreenGui and one of the ZIndexBehaviors then it’s not too bad.
I might be misunderstanding the question but doesn’t :GetGuiObjectsAtPosition return the UI objects in the order they’re layered in from highest to lowest?
Oh man I hope not, that’d be a couple hours wasted on my part xD Luckily it was long ago that I worked on it so if that’s the case then I won’t hurt too too bad I can’t test it right now because I don’t have access to Studio, so can someone please confirm or deny it?
Thanks a lot for the tips. This managed to solve the problem. I turned out to be right that one of the invisible elements overlaps the button.
Created localScript and placed it in StarterCharacterScripts
-- https://create.roblox.com/docs/reference/engine/classes/BasePlayerGui#GetGuiObjectsAtPosition
-- GetGuiObjectsAtPosition
local UIS = game:GetService("UserInputService")
local Player = game:GetService("Players")
local plr = Player.LocalPlayer
local PlayerGui = plr.PlayerGui
UIS.InputEnded:Connect(function(input, clickBtn)
warn("========================================")
if input.UserInputType == Enum.UserInputType.MouseButton1 then
local pos = input.Position
local guisAtPosition = PlayerGui:GetGuiObjectsAtPosition(pos.X, pos.Y)
warn(guisAtPosition)
for k,v in pairs(guisAtPosition) do
print(k,v:GetFullName())
end
end
warn("========================================")
end)
If you want to fix this issue where “invisible elements overlaps your buttons”, then loop through all the guisAtPosition, check if their .Active property is true, if false remove them from the table, before checking for which guiElement that is on top. This does so you manually can assign which frames that should act as a overlap barrier.
In this case, I made it easier - I resized the frame so that it does not overlap the button.
In my projects I use ScreenGui.Enable = false for hidden objects.
It was not my project and they danced from frames …
Well, it all depends on your use case ofc. The method mentioned, can do so buttons cannot be clicked if behind other guis for example, since you can turn on .Active on the frame that acs as another gui’s background.