1

基本问题:当玩家在由多个碰撞器组成的平面上移动时,Unity 的物理引擎会产生奇怪的碰撞。鬼碰撞发生在 Colliders 之间的关节处,并表现为两种行为:

碰撞发生时玩家从左向右移动

根据 Bennett Foddy 的演讲,这似乎是一般物理引擎的问题:

https://www.youtube.com/watch?v=NwPIoVW65pE&ab_channel=GDC

游戏细节:在我的例子中,玩家正在通过一个程序生成的虫洞,该虫洞由使用 MeshCollider 的 Segment 对象组成。虫洞在 3D 空间中随机扭曲,而宽度和高度则动态变化。玩家可以在隧道内部进行 360 度扫射(重力方向与位置相关)。

这使得我发现的更简单的解决方案变得不切实际。其中包括:

  1. 使用单个对象而不是多个对象
  2. 在关节后面放置多余的碰撞器

我设法在 OnCollisionEnter() 中标记了这些错误的碰撞。PlayerController 上的这个方法可以很好地识别这些错误的碰撞,并引发一个标志。

private void OnCollisionEnter(Collision other)
{
    if (other.gameObject.tag != "Tunnel"){return;}

    // Bit mask for tunnel layer.
    int tunnelLayerMask = 1 << 10;

    // Get the direction from the nearest Segment's origin to the collision point.
    Vector3 toCollision = other.contacts[0].point - nearestSegment.transform.position;
 
    if (Physics.Raycast(nearestSegment.transform.position, toCollision, out RaycastHit hit, 100f, tunnelLayerMask))
    {
        // Flag the collision if the detected surface normal 
        // isn't equal to the collision normal.
        if (other.contacts[0].normal != hit.normal) { colFidelityFlag = true; }
    }
}

但是在优雅地解决问题时,我完全不知所措。

目前,我只是在每帧缓存玩家的速度。如果标记了碰撞,我会用前一帧的缓存速度覆盖结果速度。这适用于大多数情况:玩家在不知不觉中进入地板一帧,并越过有问题的关节。但是在足够高的速度或与隧道内的障碍物相互作用的情况下,玩家有可能被弹出地板并进入太空。我不想过多地限制玩家的速度,因为游戏的感觉部分依赖于高速和硬碰撞。

有谁知道解决这些错误碰撞的更好方法?

4

1 回答 1

-1

这被称为“幽灵顶点”,如果你有 2 个盒子对撞机(或等效的东西)并且它们相互连接,就会发生这种情况。您可以尝试加入对撞机,这样您就有一个单独的连接对撞机,而不是 2 个单独的连接对撞机。

这里更详细地解释了幽灵顶点:https ://www.iforce2d.net/b2dtut/ghost-vertices

于 2021-02-11T09:11:27.247 回答