GetGuiObjectsAtPosition in a SurfaceGui

I have a Vector2 coordinate on a SurfaceGui, and I want to get the GuiObjects that contain that point, similar to how GetGuiObjectsAtPosition works for on screen GUIs. Is there any way I could accomplish that?

Most gui’s to put them in a position you use Udim2.new()

GetGuiObjectsAtPosition only works with Gui objects in PlayerGui, so you will have to put the SurfaceGui in PlayerGui (and set its Adornee to the object you want it to be displayed on) and project your Vector2 to the Camera and call GetGuiObjectsAtPosition with that.

Taking all the GuiObjects, getting their starting and ending x/y positions, and seeing if your point is within that range should work.

Here’s some code, assuming script.Parent is the SurfaceGui

local objectList = {}
local yourPoint = Vector2.new(150, 10)
for i, object in ipairs(script.Parent:GetDescendants()) do
	if (object:IsA("GuiObject")) then
		if (
			yourPoint.X >= object.AbsolutePosition.X 
			and yourPoint.X <= object.AbsolutePosition.X + object.AbsoluteSize.X
			and yourPoint.Y >= object.AbsolutePosition.Y
			and yourPoint.Y <= object.AbsolutePosition.Y + object.AbsoluteSize.Y
		) then
			objectList[#objectList+1] = object
		end
	end
end
1 Like

Here’s what I wrote:

function GetGuiObjectsAtPosition(screenGui, point)
    local function isPointInGui(gui, point)
        local size = gui.AbsoluteSize
        local topLeft = gui.AbsolutePosition
        local bottomRight = gui.AbsolutePosition + Vector2.new(1, 1) * size

        if topLeft.X < point.X and bottomRight.X > point.X and topLeft.Y < point.Y and bottomRight.Y > point.Y then
            return true
        end
    end

    local objects = {}

    for _, obj in next, screenGui:GetDescendants() do
        if obj:IsA("GuiObject") and isPointInGui(obj, point) then
            table.insert(objects, obj)
        end
    end

    return objects
end
1 Like

I figured as much, the lurking feeling that there was some more efficient built-in way of doing it kept nagging me though. Thanks!