Check if UI elements/RectTransform are overlapping
15,304
Solution 1
Convert the RectTransform
to Rect
then check if it overlaps.
Here is a simple function that can do that:
bool rectOverlaps(RectTransform rectTrans1, RectTransform rectTrans2)
{
Rect rect1 = new Rect(rectTrans1.localPosition.x, rectTrans1.localPosition.y, rectTrans1.rect.width, rectTrans1.rect.height);
Rect rect2 = new Rect(rectTrans2.localPosition.x, rectTrans2.localPosition.y, rectTrans2.rect.width, rectTrans2.rect.height);
return rect1.Overlaps(rect2);
}
Usage:
public RectTransform uiRect1;
public RectTransform uiRect2;
void Update()
{
if (rectOverlaps(uiRect1, uiRect2))
{
Debug.Log("Overlaps");
}else
{
Debug.Log("Does not Overlap");
}
}
Even better, make it an extension method:
public static class ExtensionMethod
{
public static bool rectOverlaps(this RectTransform rectTrans1, RectTransform rectTrans2)
{
Rect rect1 = new Rect(rectTrans1.localPosition.x, rectTrans1.localPosition.y, rectTrans1.rect.width, rectTrans1.rect.height);
Rect rect2 = new Rect(rectTrans2.localPosition.x, rectTrans2.localPosition.y, rectTrans2.rect.width, rectTrans2.rect.height);
return rect1.Overlaps(rect2);
}
}
Now, you can do
public RectTransform uiRect1;
public RectTransform uiRect2;
void Update()
{
if (uiRect1.rectOverlaps(uiRect2))
{
}
//OR
if (uiRect2.rectOverlaps(uiRect1))
{
}
}
Solution 2
Updated version considering scale of the rectTransform.
public static class RectTransformExtensions
{
public static bool Overlaps(this RectTransform a, RectTransform b) {
return a.WorldRect().Overlaps(b.WorldRect());
}
public static bool Overlaps(this RectTransform a, RectTransform b, bool allowInverse) {
return a.WorldRect().Overlaps(b.WorldRect(), allowInverse);
}
public static Rect WorldRect(this RectTransform rectTransform) {
Vector2 sizeDelta = rectTransform.sizeDelta;
float rectTransformWidth = sizeDelta.x * rectTransform.lossyScale.x;
float rectTransformHeight = sizeDelta.y * rectTransform.lossyScale.y;
Vector3 position = rectTransform.position;
return new Rect(position.x - rectTransformWidth / 2f, position.y - rectTransformHeight / 2f, rectTransformWidth, rectTransformHeight);
}
}
Author by
Jim
Updated on June 09, 2022Comments
-
Jim almost 2 years
I'd like to know how I check whether two UI Panels on my Unity Canvas are overlapping each other.
Currently I am doing this by comparing the canvas elements Rects
Canvas Settings
- Render Mode: Screen Space - Camera
- Pixel Perfect: [Yes]
- Render Camera: Main Camera
- Plane Distance: 100
- Sorting Layer: Default
- Order In Layer: 0
Canvas Scaler Settings
- UI Scale Mode: Constant Pixel Size
- Scale Factor: 1
- Reference Pixels Per Unit: 100
Code I am using to check
[Header("Check For Overlap")] public RectTransform PlayerBar; public RectTransform LeftBar; public Rect RectOne; public Rect RectTwo; public bool overlapping; //Check if the two canvas element Rects overlap each other public void CheckForOverlap() { overlapping = false; // Convert Canvas RectTransforms to World Rects RectOne = GetWorldRect(LeftBar); RectTwo = GetWorldRect(PlayerBar); if (RectOne.Overlaps(RectTwo)) { overlapping = true; } } public Rect GetWorldRect(RectTransform rt) { // Get World corners, take top left Vector3[] corners = new Vector3[4]; rt.GetWorldCorners(corners); Vector3 topLeft = corners[0]; // Rect Size ... I'm not sure if this is working correctly? Vector2 size = new Vector2(rt.rect.size.x, rt.rect.size.y); return new Rect(topLeft, size); }
What happens
'Overlapping' bool instantly changes to true.
The Rect One returns as (example)
X -7.5, Y 2.5 W 98.5, H 164.1667
-
Jim about 7 yearsThanks a lot, this was really useful. Especially the added tip for an extension method
-
Brackets about 5 years
RectTransform
already hasrect
object, wouldn't using it be less memory expensive? -
WreckFish over 3 yearsThis only works if both objects have the same parent. How would you do this if this is not a guarantee?
-
oneiros over 3 yearsI don't see any projection in screen coordinates - you are only ignoring the z coordinate. This should projected first to screen coordinates.
-
krehwell over 3 yearsthis script is so much better in my testing. it detects very well. thank you.
-
PNarimani over 3 yearsThis doesn't work when anchors are not in the same position because
sizeDelta
will be zero.