Check If ANY Two Gui's Are Touching

So I have a main guiObject and I want to get if it is touching any other guiObject in that frame but the internet only has solutions for two specific guis. I only have one specific gui and then any others that are touching. Does anyone know how I can get this working?

1 Like

Maybe this can help:

Please have a research first, before starting a topic.

You can use a module like the GuiCollisionService.


If you just need something simple to check if two gui’s are colliding, and assuming your GuiObject is rectangular and not rotated, you can check collisions on every corner of each Gui by doing something like this with a LocalScript.

local Player = game:GetService("Players").LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
function GatherGUIsTouching(GUIObject)
	local TouchingGUIs = {}
	local Corners = {
		TopLeftCorner = Vector2.new( GUIObject.AbsolutePosition.X, GUIObject.AbsolutePosition.Y ),
		TopRightCorner = Vector2.new( GUIObject.AbsolutePosition.X + GUIObject.AbsoluteSize.X, GUIObject.AbsolutePosition.Y),
		BottomLeftCorner = Vector2.new( GUIObject.AbsolutePosition.X, GUIObject.AbsolutePosition.Y + GUIObject.AbsoluteSize.Y),
		BottomRightCorner = Vector2.new( GUIObject.AbsolutePosition.X + GUIObject.AbsoluteSize.X, GUIObject.AbsolutePosition.Y + GUIObject.AbsoluteSize.Y),
	}
	for _, v in pairs(Corners) do
		for _, TouchingObject in pairs (PlayerGui:GetGuiObjectsAtPosition(v.X,v.Y)) do
			table.insert(TouchingGUIs, TouchingObject)
		end
	end
	return TouchingGUIs
end

function GuisAreTouching(Gui1,Gui2)
	if not Gui1 or not Gui2 then return end
	if typeof(Gui1) ~= "Instance" or typeof(Gui2) ~= "Instance" then return nil end
	if not Gui1:IsA("GuiBase2d") or not Gui2:IsA("GuiBase2d") then return nil end
	local TouchingStatus = false
	if table.find(GatherGUIsTouching(Gui1), Gui2) then
		TouchingStatus = true
	end
	if table.find(GatherGUIsTouching(Gui2), Gui1) then
		TouchingStatus = true
	end
	return TouchingStatus
end

local Gui1 = nil
local Gui2 = nil
repeat wait() until Player.Character --Make sure the player adjusts the gui properties on spawn according to their screen otherwise collisions won't be properly detected using the GetGuiObjectsAtPosition() function.
wait (1)
print(GuisAreTouching(Gui1,Gui2))

An alternative method (if you aren’t using player-based guis) is by comparing every pixel in each GuiObject. Note that this method isn’t efficient and can greatly affect performance since it’s running intertwined loops and will be slower the larger the gui size. This example manually detects if there is any overlap in any pixels.

function ConvertGUIToTable(GUIObject)
	if typeof(GUIObject) ~= "Instance" then return end
	if not GUIObject:IsA("GuiBase2d") then return end
	local PixelsInGui = {}
	local Height = GUIObject.AbsoluteSize.Y
	local Width = GUIObject.AbsoluteSize.X
	for CurrentY = 0, Height do
		for CurrentX = 0, Width do 
			table.insert(PixelsInGui, Vector2.new( ( (GUIObject.AbsolutePosition.X - math.ceil(Width/2) ) + CurrentX) , (GUIObject.AbsolutePosition.Y - math.ceil(Height/2) ) + CurrentY)) --Records each pixel into the PixelsInGui table.
		end
	end
	return PixelsInGui
end

function Compare2Tables(Table1,Table2)
	if typeof(Table1) ~= "table" or typeof(Table2) ~= "table" then return nil end
	local FoundDupe = false
	for i,v in pairs (Table1) do
		if table.find(Table2,v) then
			FoundDupe = true
			break
		end
	end
	return FoundDupe
end

local Gui1 = nil
local Gui2 = nil
local GuisAreTouching = Compare2Tables(ConvertGUIToTable(Gui1), ConvertGUIToTable(Gui2))
print(GuisAreTouching)

Your best option IMO is to use the GuiCollisionService module since they’ve done all of the hard calculations for you.

1 Like