修复由多个碰撞体组成的飞机上的幽灵碰撞?

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

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

根据 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; }
    }
}

但是当谈到优雅地解决这个问题时我完全不知所措。

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

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

unity-game-engine collision-detection physics-engine mesh-collider
2个回答
0
投票

面对类似的问题,您最终找到解决办法了吗? (抱歉,这是一个答案,我没有足够的“声誉”来发表评论......)


-1
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.