如何获取PolygonCollider2D点的世界空间位置?

问题描述 投票:0回答:2

我正在尝试编写一个涉及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作为中心,但这也不起作用。

c# unity-game-engine polygon bounds
2个回答
0
投票

我的猜测是,这可能不起作用,因为您试图将 TransformPoint 的结果分配给对撞机上的点。

尝试使用另一个变量来存储 Vector2,并检查它是否有效。试试这个:

Vector2 worldSpacePoint = otherPolygonCollider.transform.TransformPoint( otherPolygonCollider.points[ i]); 

您还可以使用playerCollider.bounds.Contains方法来检查玩家是否正在触摸顶点。

希望这有帮助。


0
投票

根据 文档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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.