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
Canvas Scaler Settings
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
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);
    }
}
                        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))
    {
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With