检查UI元素/ RectTransform是否重叠

我想知道如何检查Unity Canvas上的两个UI面板是否相互重叠。

目前我通过比较canvas元素Rects来做到这一点

canvas设置

  • 渲染模式:屏幕空间 – 相机
  • 像素完美:[是]
  • 渲染相机:主相机
  • 平面距离:100
  • 排序图层:默认
  • 在图层中排序:0

canvas缩放器设置

  • UI缩放模式:恒定像素大小
  • 比例因子:1
  • 参考像素每单位:100

我用来检查的代码

[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); } 

怎么了

‘重叠’布尔立即变为真。

Rect One返回(示例)

X-7.5,Y 2.5 W 98.5,H 164.1667

RectTransform转换为Rect然后检查它是否重叠。

这是一个可以做到这一点的简单函数:

 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); } 

用法

 public RectTransform uiRect1; public RectTransform uiRect2; void Update() { if (rectOverlaps(uiRect1, uiRect2)) { Debug.Log("Overlaps"); }else { Debug.Log("Does not Overlap"); } } 

更好的是,使它成为一种扩展方法:

 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); } } 

现在,你可以做到

 public RectTransform uiRect1; public RectTransform uiRect2; void Update() { if (uiRect1.rectOverlaps(uiRect2)) { } //OR if (uiRect2.rectOverlaps(uiRect1)) { } } 

考虑到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); } }