Search Unity

'Bullet' object triggering multiple colliders on enemies in same position before destroying

Discussion in 'Scripting' started by Emolk, Aug 12, 2019.

  1. Emolk

    Emolk

    Joined:
    Feb 11, 2014
    Posts:
    241
    Pretty much title. I have an object that my player shoots that acts like a bullet but can bounce of walls etc.

    Since this game is a 2D platformer, with the basic enemy movement i have at the moment, enemies of the same type get clumped together in the exact same position and so their colliders are in the same position. What happens is my 'bullet' object hits the clumped up enemies, dealing damage to all of them (since it hits all the enemies) before destroying itself.

    How do i get the 'bullet' object to only hit one enemy when they are in the same position as another enemy?

    Thanks.
     
  2. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    How is your bullet object set up?

    Typically, I would have a boolean variable on the bullet which records whether or not it has already dealt damage. When a hit is detected, check the value of this variable before dealing damage. If the value is "false" then deal the damage and set it to "true". If the value is already "true" then do nothing.
     
    Joe-Censored likes this.
  3. Emolk

    Emolk

    Joined:
    Feb 11, 2014
    Posts:
    241
    The bullet destroys itself on collision. Surely the boolean wouldn't change anything?

    OnTriggerEnter2D is called on the enemies at the same time, the bool wouldn't change this, right?
     
  4. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    If you're not using DestroyImmediate then yes, boolean might change a lot. My personal way of doing bullets like this one is to save collision info on first collision enter, disable collider and rigidbody, handle collision in next Update, destroy the bullet (usually after playing hit animation).
     
  5. Emolk

    Emolk

    Joined:
    Feb 11, 2014
    Posts:
    241
    The bullet enters the triggers at the same time though since they are in the same position?

    EDIT: Tried the boolean and it didn't work..
     
  6. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    The movement is not continious, therefore it is possible to collide with multiple objects at the same time. In this case unity will call collision enter function multiple times per frame. If you save disabled the collider at first call, next calls won't happen. That's the solution to your problem.
     
  7. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Destroy schedules the object to be destroyed before the next frame. It does not immediately destroy the object. DestroyImmediate does that, but destroying an object in the middle of a frame can cause its own problems, and is specifically not recommended in the documentation. The bool solution is the simple fix.
     
    angrypenguin likes this.
  8. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Can you please show us what you've got? Until we've got details we're just guessing.
     
  9. Emolk

    Emolk

    Joined:
    Feb 11, 2014
    Posts:
    241
    Yep sorry.

    Enemy class

    Code (CSharp):
    1. void OnTriggerEnter2D(Collider2D col){
    2.  
    3.         body = gameObject.GetComponent<Rigidbody2D>();
    4.  
    5.  
    6.         if (col.gameObject.tag == "Attack"){
    7.             float knockbackForce = col.gameObject.GetComponent<AttackClass>().knockbackForce;
    8.  
    9.             // Add all enemies that can't be knockbacked here
    10.  
    11.             if (type != "Ghost"){
    12.                 knockback(knockbackForce, col.gameObject);
    13.             }
    14.             takeDamage(col.gameObject.GetComponent<AttackClass>().baseDamage);
    15.         }
    16.        
    17.     }
    'Bullet' class

    Code (CSharp):
    1. void OnTriggerEnter2D(Collider2D col){
    2.  
    3.         if (col.gameObject.tag == "Enemy"){
    4.             // AudioManager.GetComponent<AudioManager>().PlaySound("Pop");
    5.             Destroy(gameObject);
    6.         }
    7.        
    8.     }
     
  10. mugewara

    mugewara

    Joined:
    Feb 13, 2018
    Posts:
    3
    I know this is old, but I think I have the solution.


    Code (CSharp):
    1. void OnTriggerEnter(Collider other) {
    2. damageEnemy(damageAmount);
    3.  
    4. // This is important
    5. GetComponent<Collider>().enabled = false
    6. }
    s