Help needed with detecting whether or not two frames are touching

Hello,
I’m trying to detect when a player clicks on a frame it stops a frame and I’m trying to detect if when a player clicks, it will detect whether or not the frame is touching, and if it isn’t it will make the gui appear. But, as you can tell from my code below, I’m not doing the best job at detecting this. Please help if you can, if not have a great rest of your day!

local function checkPosition(frame, MID)
	local AS = frame.AbsoluteSize
	local AP = Lines.MID.AbsolutePosition
	
	local pos = AS.Y + AP.Y / 2 
	
	print(pos)
	
	if pos == AP then
		print("pos == AP")
	end
	return pos	
end
3 Likes

Hey dude, looks like you’re on the right track for sure using absolute size and absolute position.

Looks like for now you’re just checking the y axis, so for simplicity I’m just going to go over the process for the y axis. If you need to also check the x axis, its the same thing.

So you’ll want 4 numbers, describing the endpoints of both frames.
You can get the lower bounds by:

a1 = frameA.AbsolutePosition.Y
b1 = frameB.AbsolutePosition.Y

And the upper bound by adding the size onto that:

a2 = a1 + frameA.AbsoluteSize.Y
b2 = b1 + frameB.AbsoluteSize.Y

Then check if the bounds overlap

if (b1 <= a1 and b2 <= a1) or (a2 <= b1 and a2 <= b2) then
    print('Vertical bounds do not overlap')
else
    print('Vertical bounds overlap')
end

5 Likes

Do any of these already existing topics help?

https://devforum.roblox.com/t/how-do-you-detect-if-one-frame-is-touching-another/41494

2 Likes

I have read these topics and nothing seemed to work

Can you give a screenshot or possible a model/place file with the GUI containing the objects you want to compare? It’s difficult to tell the best way to go about it for your use case without more info.

In the original code you posted, you provide MID as an argument but never actually use it, but you do have Lines.MID...., did you mean to do Lines:FindFirstChild( MID )...?

contents

These are all the objects that are used.

Thank you! This is helping me, although how would I detect if the frames aren’t touching? Here’s the code I have so far.

function checkPosition(frame, mid)
	local a1 = frame.AbsolutePosition.Y
	local b1 = mid.AbsolutePosition.Y

	local a2 = a1 + frame.AbsoluteSize.Y
	local b2 = b1 + mid.AbsoluteSize.Y

	if (b1 <= a1 and b2 <= a1) or (a2 <= b1 and a2 <= b2) then
	    print('Vertical bounds do not overlap')
	else
	    print('Vertical bounds overlap')
	end
end

Lines.InputBegan:Connect(function(input, gameProcessedEvent)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
			if LineValues.First.Value == false and not checkPosition(Lines.First, Lines.MID) then
				LineValues.First.Value = true
				tweens.First:Pause()	
			elseif LineValues.Second.Value == false and not checkPosition(Lines.Second, Lines.MID) then
				LineValues.Second.Value = true
				tweens.Second:Pause()
			elseif LineValues.Third.Value == false and not checkPosition(Lines.Third, Lines.MID) then
				LineValues.Third.Value = true
				tweens.Third:Pause()
			elseif LineValues.Fourth.Value == false and not checkPosition(Lines.Fourth, Lines.MID) then
				LineValues.Fourth.Value = true
				tweens.Fourth:Pause()
			elseif LineValues.Fifth.Value == false and not checkPosition(Lines.Fifth, Lines.MID) then
				LineValues.Fifth.Value = true
				tweens.Fifth:Pause()
			elseif LineValues.Sixth.Value == false and not checkPosition(Lines.Sixth, Lines.MID) then
				LineValues.Sixth.Value = true
				tweens.Sixth:Pause()
			elseif LineValues.Seventh.Value == false and not checkPosition(Lines.Seventh, Lines.MID) then
				LineValues.Seventh.Value = true
				tweens.Seventh:Pause()
			elseif LineValues.Eighth.Value == false and not checkPosition(Lines.Eighth, Lines.MID) then
				LineValues.Eighth.Value = true
				tweens.Eighth:Pause()
				-- tweens["TweenName"]:Cancel() returns all frames to starting position
			elseif checkPosition() then
				tweens:Cancel()
				Failed()
		end
	end
end)

Alright yeah, so you have the code I provided. The first if statement justs checks if both endpoints of a frame are on one side or the other side of the second frame‘s y endpoints. If they meet this, they aren’t touching. Otherwise they are.

Remember since only the y axis is checked, its not checking if the frames overlap on a 2D plane. Just a 1D plane.

But you’ll want the checkPosition function to tell you something, so you’ll want to use returns values. So if they overlap, return true, otherwise return false.

function checkPosition(frame, mid)
	local a1 = frame.AbsolutePosition.Y
	local b1 = mid.AbsolutePosition.Y

	local a2 = a1 + frame.AbsoluteSize.Y
	local b2 = b1 + mid.AbsoluteSize.Y

	if (b1 <= a1 and b2 <= a1) or (a2 <= b1 and a2 <= b2) then
		print('Vertical bounds do not overlap')
		return false
	else
		print('Vertical bounds overlap')
		return true
	end
end

Lines.InputBegan:Connect(function(input, gameProcessedEvent)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
			if LineValues.First.Value == false and checkPosition(Lines.First, Lines.MID) then
				LineValues.First.Value = true
				tweens.First:Pause()	
			elseif LineValues.Second.Value == false and checkPosition(Lines.Second, Lines.MID) then
				LineValues.Second.Value = true
				tweens.Second:Pause()
			elseif LineValues.Third.Value == false and checkPosition(Lines.Third, Lines.MID) then
				LineValues.Third.Value = true
				tweens.Third:Pause()
			elseif LineValues.Fourth.Value == false and checkPosition(Lines.Fourth, Lines.MID) then
				LineValues.Fourth.Value = true
				tweens.Fourth:Pause()
			elseif LineValues.Fifth.Value == false and checkPosition(Lines.Fifth, Lines.MID) then
				LineValues.Fifth.Value = true
				tweens.Fifth:Pause()
			elseif LineValues.Sixth.Value == false and checkPosition(Lines.Sixth, Lines.MID) then
				LineValues.Sixth.Value = true
				tweens.Sixth:Pause()
			elseif LineValues.Seventh.Value == false and checkPosition(Lines.Seventh, Lines.MID) then
				LineValues.Seventh.Value = true
				tweens.Seventh:Pause()
			elseif LineValues.Eighth.Value == false and checkPosition(Lines.Eighth, Lines.MID) then
				LineValues.Eighth.Value = true
				tweens.Eighth:Pause()
				-- tweens["TweenName"]:Cancel() returns all frames to starting position
			elseif not checkPosition() then
				for i,v in pairs(tweens) do
					v:Cancel()
				end
				Failed()
		end
	end
end)

Here’s my updated code and it’s still not canceling the tweens and firing the Failed function. The only thing I could think of is because at the end when I have elseif not checkPosition() then the reason I think it’s not working is because the checkPosition doesn’t have anything in the parenthesis.

1 Like

If you’re not sure why it’s not working use the output or script debugger.

Anyway checkPositions() takes in 2 parameters, and will throw an error if two aren’t provided because it will try and access the properties of a nil value.

Since this is the last elseif statement, it will only throw that error if all the above conditions are false. So if you’re program doesn’t perform any of the individual tween pauses, then you probably have more than one error in your code.

Okay thank you for all your help. Quick last question, I’m trying to reset all of my tweens by using :Cancel() which doesn’t cancel tweens. Do you know what can cancel tweens I’ve been looking up an answer and can’t seem to find one.

:Cancel() is a valid method to halt tweens. But it doesn’t revert the tween to its original values/ position. To do that, you’ll need to manually set those after cancelling the tween.
:Pause() is similar, but doesn’t reset the internal tween variables.

If you’re having trouble using either of the methods, then you might not be using them on a TweenBase object.