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