How To Check If 2 UI Elements Are Overlapping

Hi, I’m making a game similar to FNF. The title may seem simple, but 1 of the UI elements are inside a ScrollingFrame which’s CanvasPosition is also being tweened.

I have this script here, but it used to detect an overlap too early and now detects it when the note’s middle is near the key (called roll) instead.

local keybinds = game.ReplicatedStorage.Keybinds

function areFramesOverlapping(Frame1,Frame2)
	-- X axis overlap detection
	local F1posX,F2posX = Frame1.AbsolutePosition.X,Frame2.AbsolutePosition.X
	local F1sizeX,F2sizeX = Frame1.AbsoluteSize.X,Frame2.AbsoluteSize.X

	local Xdistance = math.abs(F1posX-F2posX) -- distance (in px) between frames
	local minXdistance = math.abs(F1sizeX-F2sizeX/10)-- min distance w/o overlap

	if Xdistance < minXdistance then return true end -- OVERLAP!!

	return false -- no overlap detected
end

game.UserInputService.InputBegan:Connect(function(input)
	if script.Parent.Parent.Charter.Enabled == true then return end
	
	if input.KeyCode == Enum.KeyCode[keybinds.Key1.Value] then
		for _, v in pairs(script.Parent.Notes:WaitForChild("OncomingNotes"):GetChildren()) do
			if areFramesOverlapping(script.Parent.Notes.Keys.Roll1, v) == true then
				v:Destroy()
			end
		end
	end
end)

Preferably, I’d like it to check multiple different areas to reward the proper score, like FNF, but even detecting 1 overlap is fine.

Here’s a video of what’s happening.

I really hope my post won’t get ignored… again

1 Like

exactly what i didnt want to happen

Bumping your post wont get you any more help than it would have, before.

Couldn’t you check the position of the hit/key and reward based off the distance from said key?

You could use some method to get the bounds of each of the UI objects (I don’t know how off the top of my head), and then use StarterGui:GetGuiObjectsAtPosition() to see if they are overlapping. It’s just a basic idea, it could be adapted to be much better.

i might be doing it wrong but this always returns *doodoo*

function areFramesOverlapping(Frame1,Frame2)
	-- X axis overlap detection
	local F1posX,F2posX = Frame1.AbsolutePosition.X,Frame2.AbsolutePosition.X
	local F1sizeX,F2sizeX = Frame1.AbsoluteSize.X,Frame2.AbsoluteSize.X

	local Xdistance = math.abs(F1posX-F2posX)
	if Xdistance >= 20 then return "*doodoo*" end
	if Xdistance >= 30 then return "Bad" end
	if Xdistance >= 50 then return "Good" end
	if Xdistance >= 100 then return "Perfect" end

	return "Miss" -- no overlap detected
end

Your values are inversed…? The value should be smaller the closer it is to the ui.

i forgot to mention that i inverted them to see if they change at all, but no matter what it returns the same thing

It has to be an issue with you. On my side, I receive no such errors.

the issue is that 1 frame is inside a scrolling frame and the other isn’t, and the scrolling frame’s Canvas Position is being tweened as well
image

this doesnt work either but again i might be doing it wrong, since i’ve never used GetGuiObjectsAtPosition()

function areFramesOverlapping(Frame1)
	return game.Players.LocalPlayer.PlayerGui:GetGuiObjectsAtPosition(Frame1.Position.X.Scale+Frame1.Size.X.Scale/2, Frame1.Position.Y.Scale)
end

game.UserInputService.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.C then
		for _, v in pairs(areFramesOverlapping(script.Parent.Notes.Keys.Roll1)) do
			if v:IsA("Frame") and v.Name == "Note" then
				local rollStroke = script.RollStroke:Clone()
				game:GetService("TweenService"):Create(rollStroke, TweenInfo.new(v.Size.X.Scale * 3), {Transparency = 1}):Play()
				rollStroke.Parent = script.Parent.Notes.Keys.Roll1
				wait(v.Size.X.Scale * 3)
				rollStroke:Destroy()
				v:Destroy()
			end
		end
	end
end)

I think you need to use AbsolutePosition, as GetGuiObjectsAtPosition takes a Vector2 (I’m pretty sure, it doesn’t explicitely state that). You’ll still need to calculate the position of each edge. You might want to account for the GuiInset as well because GetGuiObjectsAtPosition accounts for that, you can get it through GuiService:GetGuiInset().

I’ve never used it either so I hope I am helping…

AbsolutePosition doesnt seem to work either

Translated to Roblox you could do something like this:

local function checkObjectsOverlap(a: GuiObject, b: GuiObject)
	local aAbsPos = a.AbsolutePosition
	local aAbsSize = a.AbsoluteSize
	
	local bAbsPos = b.AbsolutePosition
	local bAbsSize = b.AbsoluteSize
	
	local aLeft = aAbsPos.X
	local bLeft = bAbsPos.X
	
	local aRight = aLeft + aAbsSize.X
	local bRight = bLeft + bAbsSize.X
	
	local aTop = aAbsPos.Y
	local bTop = bAbsPos.Y
	
	local aBottom = aTop + aAbsSize.Y
	local bBottom = bTop + bAbsSize.Y
	
	return aLeft < bRight and aRight > bLeft and bTop < aBottom and bBottom > aTop
end

Hopefully this works for you