我正在尝试编写一个涉及PolygonCollider2D的编辑器工具,但问题是用户在编辑器中定义的多边形点与PolygonCollider2D.bounds.center + PolygonCollider2D.points不对应。根据文档,Bounds位于世界空间中,而点位于本地空间中,因此要获取点的世界空间位置,您需要将每个点添加到bounds.center,如下所示:
Vector2 p1 = (Vector2)polygon.bounds.center + polygon.points[i];
但是,在执行此操作并调试绘制点时,UI 定义的点和数学导出的点之间存在差异。碰撞体越大,误差就越大。这是我用来调试它的脚本。
List<Vector2> debugPositions = new();
public void OnSceneGUI()
{
for (int i = 0; i < debugPositions.Count; i++)
Handles.DrawSolidRectangleWithOutline(new Rect(debugPositions[i].x, debugPositions[i].y, 0.2f, 0.2f), Color.cyan, Color.black);
}
void GetPolygonPointsWorldPos(PolygonCollider2D polygon)
{
debugPositions.Clear();
// Loop through the points of the polygon
for (int i = 0; i < polygon.points.Length; i++)
{
//Get the world space pos of point and next point (wrap around if needed)
Vector2 p1 = (Vector2)polygon.bounds.center + polygon.points[i];
Vector2 p2 = (Vector2)polygon.bounds.center + polygon.points[(i + 1) % polygon.points.Length];
debugPositions.Add(p1);
debugPositions.Add(p2);
}
}
我唯一能想到的是,也许bounds.center实际上并不是中心,但我尝试过使用transform.position作为中心,但这也不起作用。
我的猜测是,这可能不起作用,因为您试图将 TransformPoint 的结果分配给对撞机上的点。
尝试使用另一个变量来存储 Vector2,并检查它是否有效。试试这个:
Vector2 worldSpacePoint = otherPolygonCollider.transform.TransformPoint( otherPolygonCollider.points[ i]);
您还可以使用playerCollider.bounds.Contains方法来检查玩家是否正在触摸顶点。
希望这有帮助。
根据 文档bounds.center 是边界框的中心,这意味着它不是点相对于的世界位置。
我很确定世界位置就是 Polygon.transform.position
你应该能够通过说
来获得一个点的世界位置polygon.transform.position + polygon.points[i]
编辑澄清:
下图显示了一个游戏对象上仅包含 PolygonCollider2D 的场景,以及我用于绘制点的脚本。
青色:局部空间中的点。和
polygon.points[i]
一样
蓝色:世界空间中的点。和
polygon.transform.position + polygon.points[i]
一样
绿色:点的中心。这与游戏对象的位置相同,即
polygon.transform.position
红色:边界框上的点。正如你所说,这些确实在世界空间中。
黄色:边界框的中心。请注意,该中心与点的中心不同。
如您所见,世界空间中的点的位置是相对于游戏对象的位置,而不是边界框的位置。
代码:
public class PolygonColliderTest : MonoBehaviour
{
[SerializeField] private PolygonCollider2D polygon;
private void OnDrawGizmos()
{
// Local position of the points
Gizmos.color = Color.cyan;
foreach (var point in polygon.points)
{
Gizmos.DrawSphere(point, 0.25f);
}
// World position of the points
Gizmos.color = Color.blue;
var ppos = polygon.transform.position;
var center = new Vector2(ppos.x, ppos.y);
foreach (var point in polygon.points)
{
Gizmos.DrawSphere(center + point, 0.25f);
}
// Center of the points in world space
Gizmos.color = Color.green;
Gizmos.DrawSphere(center, 0.25f);
// Bounding box
Gizmos.color = Color.red;
var bcenter = polygon.bounds.center;
var bmin = polygon.bounds.min;
var bmax = polygon.bounds.max;
var bp1 = bmin;
var bp2 = bmax;
var bp3 = new Vector3(bmin.x, bmax.y);
var bp4 = new Vector3(bmax.x, bmin.y);
var bps = new Vector3[4] { bp1, bp2, bp3, bp4 };
foreach (var point in bps)
{
Gizmos.DrawSphere(point, 0.25f);
}
// Center of the bounding box in world space
Gizmos.color = Color.yellow;
Gizmos.DrawSphere(bcenter, 0.25f);
}
}