【问题标题】:Fixing ghost collisions on a plane made of multiple Colliders?在由多个对撞机组成的飞机上修复鬼碰撞?
【发布时间】:2021-02-11 04:40:49
【问题描述】:

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

这似乎是一般物理引擎的问题,根据 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; }
    }
}

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

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

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

【问题讨论】:

    标签: unity3d collision-detection physics-engine mesh-collider


    【解决方案1】:

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

    这里对ghost顶点有更详细的解释:https://www.iforce2d.net/b2dtut/ghost-vertices

    【讨论】:

    • 是的,这是我提到的那些简单的解决方案之一,由于游戏的性质,它不起作用。 Segment 对象动态调整大小,因此将其加入另一个 Segment 会干扰此功能....
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-21
    • 2019-04-30
    • 1970-01-01
    • 2017-09-25
    • 2020-11-11
    • 1970-01-01
    相关资源
    最近更新 更多