当 isTrigger 为真时,碰撞对象弹开而不是通过

Colliding objects bouncing off when isTrigger is true instead of passing through

我已经遍历了一些游戏对象以在特定碰撞发生之前设置 isTrigger 属性 但是尽管 属性 是真实的,但与对象的碰撞仍然发生。请看下面的相关代码:

    void OnCollisionEnter2D(Collision2D col)    {

    if (col.gameObject.tag == "object1") {
         for (int i = 0; i < badGuys.Count; i++)    {
         badGuys[i].getBadGuyGameObject().GetComponent<Collider2D>().isTrigger = true;
      }

      }

    else if (col.gameObject.tag == "object2") {

       // collision with object1 always occurs before object2, though isTrigger is true the colliding object doesn't pass through the badGuys game objects, it bounces off on collision
      }
   else if (col.gameObject.tag == "object3") {
      for (int i = 0; i < badGuys.Count; i++)   {
         badGuys[i].getBadGuyGameObject().GetComponent<Collider2D>().isTrigger = false;
      }
      }
    else if (col.gameObject.tag == "badGuy") {

      }

}

与 object1 的碰撞总是发生在 object2 之前,尽管 isTrigger 为 true 碰撞对象不会穿过 badGuys 游戏对象,它会在碰撞时反弹。我该如何解决?

更新 1

我刚刚意识到检查器中的 isTrigger 值是真还是假取决于我停止游戏的时间。例如,如果我在 Object1 碰撞后停止游戏,isTrigger 为真,而当我在与对象 3 碰撞后停止游戏时,它为假。这种不一致使得调试非常麻烦。这是错误还是什么?

更新 2

根据 Joe Blow 和 Agustin0987 的推荐,我使用 Collider2Denabled 属性 而不是 isTrigger。我还删除了 OnCollisionEnter2D 中几乎所有的代码以获得一个简单的测试场景。请看下面的代码:

void OnCollisionEnter2D(Collision2D col)    {

    if (col.gameObject.tag == "object1") {

        if (badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = false) {
            badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = true;
            Debug.Log ("CHANGED TO TRUE");
            Debug.Log ("bad guy  collider enabled is " + badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled);

        }


        else if (badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = true) {
            badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = false;
            Debug.Log ("CHANGED TO FALSE");
            Debug.Log ("bad guy collider enabled is " + badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled);


        }
    }
    else if (col.gameObject.tag == "badGuy") {
       Debug.Log("collided with bad guy"); // DOESN'T OCCUR
    }

}

这次我没有循环,而是决定测试一个。 else ifenabledtrue 的地方,虽然 Log 打印 false 并且 ifenabledfalse永不满足。在检查器中,坏人的 Box Collider2D 始终处于未选中状态。永远不会发生与 badGuy 的碰撞。根据我的简单场景代码,我认为它应该可以工作。

似乎您正在尝试 enable/detect badGuysobject2 之间的碰撞,仅当 object1 与附加此脚本的任何对象发生碰撞时(似乎是某种 BadGuyManager)。所以我建议不要将 isTrigger 设置为 true 或 false,你应该尝试启用或禁用整个 `Collider2D.

P.S:我同意 Joe Blow 的观点,你应该解释你想要实现的目标。

从来没有,曾经

我的意思是绝对从不

使用“else if”。

简单地说,永远,永远 - 永远 - 在你的余生中输入“else if”,直到你死去。

首先,删除所有代码并将其替换为:

void OnCollisionEnter2D(Collision2D col)
{
Debug.Log("We will deal with this ......... " +col.gameObject.name);
if (col.gameObject.tag == "object1")
    {
    Debug.Log("\t handling 'object' type issue");
    HandleObjectIssue(col)
    return; //NOTE HERE
    }
if (col.gameObject.tag == "object1")
    {
    Debug.Log("\t handling 'bad guy' type issue");
    HandleBadGuyIssue(col)
    return; //NOTE HERE
    }
}

private void HandleObjectIssue(Collision2D col)
{
Debug.Log("'\t\t object', I'm dealing with this .. " +col.gameObject.name);
}


private void HandleBadGuyIssue(Collision2D col)
{
Debug.Log("\t\t 'badguy', I'm dealing with this .. " +col.gameObject.name);
}

运行 对它进行广泛的“单元测试”。如果您愿意,可以将(使用该代码)转换回“循环”方法以查看所有项目。无论如何,请广泛测试。

--

其次,添加这个例程..

private void ToggleColliderOnGameObject( GameObject gg )
{
Debug.Log("I'm supposed to toggle the collider on: " +gg.name);
Collider2D { or whatever } col = gg.GetComponent<Collider2D>();
bool currentState = GetComponent<Collider2D>().enabled;

Debug.Log("\t it is currently: " +currentState);

bool newState = ! currentState;
col.enabled = newState;

Debug.Log("\t\t but now it is: " +newState);
}

...并用它开始单元测试。所以你会有这样的代码:

 ToggleColliderOnGameObject( badGuys[4].getBadGuyGameObject() );

例如,尝试这样的事情:

void Start()
    {
    InvokeRepeating("teste", 1f, 1f);
    }
private void Teste()
    {
    ToggleColliderOnGameObject( badGuys[4].getBadGuyGameObject() );
    }

经过一段时间的实验和单元测试后,您将能够继续前进。

请注意,除了其他问题,很可能(例如)您的例程“getBadGuyGameObject”返回了错误的东西 - 或者一些类似的问题。

编辑:

从您的 public void createBadGuy(GameObject badGuyPrefab, BadGuyType badGuyType, Vector3 badGuyPosition) 函数中删除 badGuy = badGuyPrefab;。这是您评论中 link 中程序员代码中的一个错误。