Search Unity

OnTriggerEnter2D keeps colliding for sometime after being destroyed

Discussion in 'Scripting' started by goodgamershow, Jun 28, 2021.

  1. goodgamershow

    goodgamershow

    Joined:
    Apr 5, 2021
    Posts:
    15
    I have 3 game objects: 1st is enemy, 2nd is player and 3rd is shield.

    Enemy has a circle collider2d and IsTrigger checked.

    Player has rigidbody2d + circle collider2d.

    Shield has a circle collider2d and IsTrigger checked + it's Player's child(So it would move with Player). Shield's collider is slightly bigger than Player's collider.

    When enemy hits a player(i.e player is inside trigger collider), then player takes damage, but if Shield gameObject is active, then Enemy collides with shield and shield's SetActive is set to false again and enemy disappears(Destroys), without touching Player's collider(Because as I said, shield's collider is slightly bigger, than player's, that's why enemy must first collide with shield's collider).

    So here's the problem: By default Player's shield is SetActive(false) and when player receives a buff(pressing button B), then Player's shield SetActive is set to true. When enemy collides with shield, it sets the shield gameObject back to false(which is correct), but then also it damages the player, and then enemy disappears. Even when checking the console, it's shown that enemy first collides with shield, and then immidiately with the player(but sometimes for some reason it collides with player first, and then with the shield, maybe because player is moving?)But sometimes code works as intended, i.e shield disappears and player doesn't take damage(chance for correct work of OnTriggerEnter2D is 50%/50%, but if player moves at high speed, absolutely always enemy destroys the shield and damages player) Here's the code of the enemy:
    Code (CSharp):
    1. private void OnTriggerEnter2D(Collider2D other) {
    2.           if(other.CompareTag("Player_Shield")){
    3.               Destroy(gameObject);
    4.               other.gameObject.SetActive(false); //turning off the shield
    5.               Debug.Log("Collided with shield");
    6.           }else if(other.CompareTag("Player")){
    7.               playerRef.TakeDamage(1);
    8.               Destroy(gameObject);
    9.               Debug.Log("Collided with player");
    10.           }
    11.       }
     
  2. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,647
    From what I've read, an object with a RigidBody will handle all of its child colliders, so your Player object is handling the collider of both the shield and the player.

    You could instead have one script on the Player which checks if the shield is Active, and take damage/disable the shield depending on its Active state.
     
    goodgamershow and Brathnann like this.
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,455
    More specifically, all colliders are always created via a physics body and are permanently attached to it. They don't exist on their own and cannot. When there's a collision/trigger (contact) the callbacks happen on the Collider2Ds and if the associated Rigidbody2Ds are not on the same GameObject, the callbacks happen there too.
     
    goodgamershow and RadRedPanda like this.
  4. goodgamershow

    goodgamershow

    Joined:
    Apr 5, 2021
    Posts:
    15
    Thank you for your responses, both @MelvMay & @RadRedPanda ! I can not believe I didn't think of checking IsActive of shield gameObject before. This really sounds like a good solution. You guys fixed my problem which caused me a lot of headache + you also pointed me to the solution which requires no code for player_Shield gameObject.
    Thank you very much!