Unity中非矩形区域填充占比计算失效问题排查
问题原因与解决方案
嘿,这个问题我之前做关卡覆盖率统计的时候也踩过坑,咱们来唠唠为啥会这样~
为啥矩形好用,非矩形不行?
你用的bounds.size计算的是轴对齐包围盒(AABB)的面积,不是多边形本身的真实面积:
- 对于矩形来说,它的轴对齐包围盒就是它自己,所以用包围盒面积计算出来的结果和真实面积完全一致,差值自然准确。
- 但非矩形的不规则多边形(比如带拐角、斜边的形状),它的包围盒会把多边形周围的空白区域也包含进去。你拿这个包围盒面积去做差值,相当于把不属于橙色区域的空白也算进去了,结果肯定不准。
正确的解决方法:计算多边形真实面积
要得到准确的覆盖比例,你需要计算PolygonCollider对应的多边形的真实面积,这里最常用的是鞋带定理(Shoelace Formula),专门用来计算简单多边形的面积。
给你一段Unity里可以直接用的C#代码示例:
// 计算单个PolygonCollider2D的真实面积 public float GetPolygonColliderArea(PolygonCollider2D collider) { Vector2[] points = collider.points; float totalArea = 0f; int pointCount = points.Length; // 应用鞋带公式 for (int i = 0; i < pointCount; i++) { int nextIndex = (i + 1) % pointCount; totalArea += points[i].x * points[nextIndex].y; totalArea -= points[nextIndex].x * points[i].y; } // 取绝对值并除以2,得到最终面积 return Mathf.Abs(totalArea) / 2f; }
进阶处理:复合多边形(带洞的情况)
如果你的场地或者橙色区域是带洞的复合多边形(PolygonCollider2D的pathCount大于1),那需要分别计算每个路径的面积,注意洞的面积要从总面积里减去(因为Unity里PolygonCollider的第二个及以后的路径默认是洞):
public float GetComplexPolygonArea(PolygonCollider2D collider) { float totalArea = 0f; for (int pathIndex = 0; pathIndex < collider.pathCount; pathIndex++) { Vector2[] points = collider.GetPath(pathIndex); float pathArea = 0f; int pointCount = points.Length; for (int i = 0; i < pointCount; i++) { int nextIndex = (i + 1) % pointCount; pathArea += points[i].x * points[nextIndex].y; pathArea -= points[nextIndex].x * points[i].y; } float absArea = Mathf.Abs(pathArea) / 2f; // 第一个路径是外轮廓,加面积;后续是洞,减面积 totalArea += pathIndex == 0 ? absArea : -absArea; } return Mathf.Abs(totalArea); }
最后,用橙色区域的真实面积除以整个场地的真实面积,就能得到准确的覆盖比例啦~
内容的提问来源于stack exchange,提问作者Björn Rave
相关产品推荐
相关产品推荐

