【问题标题】:Recommended Approach to multiple colliders多个对撞机的推荐方法
【发布时间】:2015-02-16 23:28:20
【问题描述】:

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

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

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

  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 值来防止玩家在从顶部击中敌人时进入第二个对撞机 - 但显然以这种力量/速度,对撞机可能有点不准确(或者也许我只是在做错了吗?)。

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

我“暂时”使用的是一个单一的对撞机,里面有一段我不满意的简单代码,而且并不总是有效:

    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 模式的解决方案(虽然可能比我的问题所需要的更复杂)。

谢谢大家。

【问题讨论】:

  • 嗨!如果你想摧毁自己,你可以做Destroy(gameObject);。 :)
  • @Bobthezealot - 我绝对不想毁了自己 :) 我想要的是触发其中一个对撞机,而另一个不触发。在从顶部击中的情况下,两个对撞机都被触发 - 即使我试图摧毁游戏对象。
  • 不,抱歉,我的意思是您可以将 Destroy(this.gameObject); 替换为 Destroy(gameObject);
  • @ZuiqPazu 您是否在寻找哲学答案或可能的实现?无论如何,我添加了一个答案,是你要找的吗?
  • 哦,好的,谢谢你的提示 :)

标签: unity3d unity3d-2dtools


【解决方案1】:

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

一个不错的选择是您将对象附加并清空您的玩家并将其位置设置在您的玩家脚下并检查敌人击中敌人是否死亡,否则如果敌人击中主角对象,玩家就会死亡。

另一种选择是当 o 个对象发生碰撞时检查 2 个对象的 y 位置。他杀死的玩家的数量更高,否则敌人会杀死玩家。

如果你想得更多,你会找到更多答案。 您必须检查不同的方法并找到最有效的方法。

【讨论】:

  • 感谢您的解释。我知道通常 BoxCollider2D 是不够的——而且看起来也不漂亮,但由于我的图像几乎都是盒子,我认为我可以使用盒子。您提到了在碰撞时检查对象的 Y 位置,但我已经在上面粘贴的最后一个代码示例中尝试过。它并不总是有效。有时这个值比较奇怪,会触发敌人死亡——当很明显这出戏碰到它的时候。我认为这与物理有关?
  • 此外,将 GameObject 附加到玩家的脚上似乎与将 GameObject 附加到敌人的头部没有什么不同。但是,我将结合@Dinal24 的建议尝试一下,看看它是如何发展的。会让你知道的。
  • 正如我对另一个答案的评论,虽然您的答案本身并不能真正解决问题,但结合两个答案(并将其中一个对撞机设置为触发器,似乎确实有助于问题)。我会接受您提出不同选择的答案。谢谢。
  • 您说“我已经尝试过 [检查对象的 Y 位置]”,但您最初的问题显示您只检查玩家对象的 y 速度。
【解决方案2】:

我认为当一个碰撞器被触发时禁用另一个碰撞器会很容易。您可以使用collider.enabled = true;collider.enabled = false; 轻松启用/禁用碰撞器

// 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);
    }
}

这样,它将非常轻量级且易于实现。

【讨论】:

  • 澄清一下,我正在研究一种可能的实现方式,您的实现方式就足够了。但是我不知道这与我当前的实现有何不同,但我会照样试一试。会告诉你进展如何。
  • 我刚刚尝试了您提到的方法,以及@virtuoso 建议在玩家脚下使用游戏对象。然后我将其设置为触发器,并将 OnCollisionEnter2D 替换为 OnTriggerEnter2D。这似乎有效。我喜欢这两个答案,我真的希望我可以将它们都标记为答案,但是我会接受另一个答案,因为他谈到了不同的选择(尽管缺少代码)。不过谢谢...除非您还想对这个问题提出其他理论上的答案,这可能会为您赢得胜利:)
【解决方案3】:

实现您想要的一种方法是将每个对撞机放在其子自己的游戏对象中并使用 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)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-08
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 2022-10-22
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    相关资源
    最近更新 更多