多个碰撞器的推荐方法

Recommended Approach to multiple colliders

我对这可能是一件非常愚蠢的事情有些困难。我有一个敌方游戏对象,它取决于它被击中的位置(碰撞)——要么是它,要么是游戏死了。我认为最简单的描述方式是以经典的 超级马里奥兄弟 游戏为例。

众所周知,如果玩家撞到敌人 - 玩家会输 - 除非他跳到敌人的头顶上,在这种情况下敌人应该死。

我最初的想法是在游戏对象上创建两个碰撞体:

  1. 蓝色边框代表一个 BoxCollider2D - 如果与之发生碰撞 - 将导致玩家失败(注意它比顶部略低)
  2. 绿色边框表示子游戏对象上的 BoxCollider2D - 如果与之发生碰撞 - 将导致游戏对象死亡。

以下是我使用的代码的简化版本:

    // Collider #1
    public void OnCollisionEnter2D(Collision2D collision)
    {
        // Trigger 'Game-Over' logic
    }

    // Collider #2
    public void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            Destroy(this.gameObject);
        }
    }

这种方法有效,但是在与 Collider #1 碰撞后不久,Collider #2 也被触发 - 虽然敌人被消灭,玩家也输了。

我一直在玩 RigidBody2D 值,以防止玩家在从顶部击中敌人时进入第二个碰撞器 - 但显然以这种力/速度,碰撞器可能稍微不准确(或者我可能只是做错了?)。

我研究了 RayCasts,但这对于我看来相当微不足道的事情来说似乎太复杂了(在玩家的所有四个边和四个顶点上投射光线 - 假设玩家有一个盒子碰撞器)。

我求助于 'for the moment' 的是一个单一的碰撞器,带有一段我不满意的简单代码,而且并不总是有效:

    public void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            float yVelocity = collision.gameObject.transform.rigidbody2D.velocity.y;

            if (yVelocity < 0)
            {
                Debug.Log("Enemy will lose..." + yVelocity);

                Destroy(this.gameObject);
            }
            else
            {
                // Trigger 'Game-Over' logic
            }
        }
    }

我目前在 2D 模式下工作,但也将考虑 3D 模式的解决方案(虽然可能比我的问题所需的更复杂)。

谢谢大家。

作为游戏开发者,您总是有很多方法来解决问题或制作游戏玩法。 首先我不得不说你应该为你的对象和字符制作一个多边形对撞机 2d。只是碰撞图片不是很好,因为我看到你在游戏中使用了 box cilliders。

一个不错的选择可以是你附加并清空你玩家的物体并将它的位置设置在你玩家的脚下并检查敌人击中敌人是否死亡否则如果敌人击中主角物体,玩家死亡。

另一种选择可以是当 o 个物体碰撞时检查 2 个物体的 y 位置。玩家的等级越高,他就会杀死,否则敌人会杀死玩家。

想得越多,答案就越多。 你必须检查不同的方法并找到最有效的方法。

我认为当一个对撞机被触发时,很容易禁用另一个对撞机。您可以使用 collider.enabled = true;collider.enabled = false;

轻松地 enable/disable 对撞机
// Collider #1
public void OnCollisionEnter2D(Collision2D collision)
{
    // Trigger 'Game-Over' logic
    // collider2.enabled = false;
}

// Collider #2
public void OnCollisionEnter2D(Collision2D collision)
{
    // collider1.enabled = false;
    if (collision.gameObject.tag == "Player")
    {
        Destroy(this.gameObject);
    }
}

这样它会非常轻量级并且易于实现。

实现您想要的方法的一种方法是将每个对撞机放入其子游戏对象中并使用 IsTouching() 方法。

void OnTriggerEnter2D(Collider2D other){
    if(GameObject.Find("Top Trigger").GetComponent<BoxCollider2D>().IsTouching(other)){
        Destroy(transform.gameObject)
    }
    if(GameObject.Find("Bottom Trigger").GetComponent<BoxCollider2D>().IsTouching(other)){
        Destroy(other.gameObject)
    }
}