我怎样才能在冲突解决中对推出向量进行排序?

How can I go about sorting pushout vectors in collision resolution?

最近我一直在研究我的游戏,到目前为止我的 SAT 碰撞检测分辨率工作正常(我可以检测到两个多边形相交并找出正确的矢量将一个推离另一个('pushout' 向量))

但是,在将推出向量应用于其他多边形时,我遇到了 运行 问题。当一个多边形与 2 个或更多多边形接触时,我最终会得到 2 个或更多推出向量,需要以正确的顺序应用这些向量以获得真实的结果(也就是不要通过其他多边形出现故障或卡在角落上不存在)

目前,我应用每个推向量,每次应用它时,我检查多边形是否仍然与它碰撞的其他多边形相交,如果是,我继续应用其余的向量。如果没有,就停止应用,因为它们不再碰撞了。

问题在于我需要按特定顺序应用向量,而不仅仅是列表中的其他顺序。我不知道订购它们的好的解决方案。

这是我的代码(collider 是需要应用推出向量的对象)(otherColliders 是碰撞器相交的碰撞器列表):

List<Vector2> pushoutVectors = getPushoutVectors(otherColliders);

foreach (Vector2 pushout in pushoutVectors)
{
    collider.Transform.Position += pushout;

    if (!collider.checkForIntersecting(otherColliders))
        break;
}

下图是我目前的问题。有没有办法在 (0, 1) 之前获取向量 (-1, 0)?

解决方案是根据与每个对撞机中心的距离进行排序。不要从原点或类似点排序 - 按升序排列的两个碰撞器中心之间的距离排序。这可确保正确应用推出矢量,并且不会发生剪裁或卡住。

示例代码:

public struct Hit
{
    public Collider Me;
    public Collider Other;
    public Vector2 Pushout;

    public float getCenteredDistanceFromOtherSquared()
    {
        return Vector2.DistanceSquared(Me.getWorldBounds().Center, Other.getWorldBounds().Center);
    }
}
List<Hit> hits = getHits(otherColliders);

// note: this is a long function name for the sake of being clear.
// it returns the distance between the 'collider' and the 'other' collider in the collision
// its squared simply because we just need to order by size not get the actual size, so its just to prevent use of a performance-costly sqrt function
List<Hit> sortedhits = hits.OrderBy(x => x.getCenteredDistanceFromOtherSquared()).ToList();

foreach (Hit hit in sortedhits)
{
    // apply pushout
    collider.Transform.Position += hit.Pushout;

    // check if we're still colliding with any other colliders
    // if we aren't, stop applying hits
    // if we are, keep applying hits
    // this is to prevent getting stuck on edges and such
    if (!collider.checkForIntersecting(otherColliders))
        break;
}