Colliding objects bouncing off when isTrigger is t

2019-08-12 05:07发布

I have looped through some game objects to set the isTrigger property before a certain collision occurs but though the property is true collision with the object still occurs. Please see the relevant code below:

    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") {

      }

}

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. How can I solve this?

UPDATE 1

I just realized that the isTrigger value is true or false in the inspector depending on the time I stop the game. For example if I stop the game after Object1 collision the isTrigger is true and when I stop the game after collision with object3 it false. This inconsistency makes debugging very cumbersome. Is this a bug or something?

UPDATE 2

Based on recommendation from Joe Blow and Agustin0987 I used the enabled property of Collider2D instead of isTrigger. I also removed virtually all the code in OnCollisionEnter2D to get a simple test scenario. Please see code below:

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
    }

}

Instead of looping through this time, I decided to test for one. The else if is where enabled is true always satisfied though the Log prints false and the if where enabled is false is never satisfied. In the inspector, the Box Collider2D for bad guys is always unchecked. Collision with the badGuy never occurs. Based on my simple scenario code I thought it should be working.

2条回答
手持菜刀,她持情操
2楼-- · 2019-08-12 05:20

It seems like you are trying to enable/detect the collision between badGuys and object2 only if object1 collides with whatever object has this script attached (seems to be some kind of BadGuyManager). So I would recommend that instead of setting isTrigger to true or false, you should try to enable or disable the whole `Collider2D.

P.S: I agree with Joe Blow in that you should explain what are you trying to achieve.

查看更多
三岁会撩人
3楼-- · 2019-08-12 05:39

Never, ever ever

I mean absolutely never

use "else if".

Simply, never, ever - ever - type "else if" for the rest of your life, until you die.

In the first instance, delete all your code and replace it with this:

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

Run that extensively and "unit test" it. If you like, convert back (USING THAT CODE) to a "loop" method to look at all items. In any event, test that extensively.

--

Secondly, add this routine ..

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

... and start unit testing with it. So you will have code like:

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

For example, try some things like this:

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

After experimenting with that for some time and unit testing, you will be able to move on.

Note that apart from other problems, it is likely that (for example) your routine "getBadGuyGameObject" is returning the wrong thing - or some similar problem.

EDIT:

Remove badGuy = badGuyPrefab; from your public void createBadGuy(GameObject badGuyPrefab, BadGuyType badGuyType, Vector3 badGuyPosition) function. This was a mistake in Programmer's code from the link in your comment.

查看更多
登录 后发表回答