1. Help us improve the editor usability and artist workflows. Join our discussion to provide your feedback.
    Dismiss Notice
  2. We're looking for feedback on Unity Starter Kits! Let us know what you’d like.
    Dismiss Notice
  3. We’re giving 2017.1 beta testers a chance to win t-shirts and a Nintendo Switch. Read more on the blog.
    Dismiss Notice
  4. We want to know how you learned Unity! Help us by taking this quick survey and have a chance at a $25 gift card
    Dismiss Notice
  5. Are you an artist or level designer going to Unite Europe? Join our roundtables there to discuss artist features.
    Dismiss Notice
  6. Unity 5.6 is now released.
    Dismiss Notice
  7. Check out all the fixes for 5.6 on the patch releases page.
    Dismiss Notice

Invaders go past the colliders when moving too fast.

Discussion in 'Editor & General Support' started by Deathslice, Mar 20, 2017.

  1. Deathslice

    Deathslice

    Joined:
    Jan 21, 2017
    Posts:
    24
    I currently have two scripts. One script is called EnemyController that is attached to an an object called EnemyController and controls the direction in which the space invaders move as well as its rate of movement The second script is called EnemyMovement which does the actual movement of the enemy.

    For each invader that dies, EnemyController reduces the movement Delay so that the invaders move faster. The problem is once the delay is reduced down significantly and the invaders start moving really fast, for some reason they go past the colliders I have setup for them(there is a collider to the far right and far left of the screen). Any ideas on how I could fix this?

    EnemyController Script

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class EnemyController : MonoBehaviour
    5. {
    6.     public Vector3 invaderHorizontalVelocity = new Vector3(0.1f, 0, 0);
    7.     public readonly Vector3 INVADER_VERTICAL_VELOCITY = new Vector3(0, -0.1f, 0);
    8.  
    9.     private float movementDelay = 1.0f;
    10.  
    11.     private bool collidedWithWall = false;
    12.  
    13.     void Start()
    14.     {
    15.         GameObject[] invaders = GameObject.FindGameObjectsWithTag("Invader");
    16.  
    17.         foreach (GameObject invader in invaders)
    18.         {
    19.             invader.transform.parent = transform;
    20.         }
    21.     }
    22.  
    23.     public void moveDown()
    24.     {
    25.         transform.position += INVADER_VERTICAL_VELOCITY;
    26.     }
    27.  
    28.     public void setCollidingWithWall(bool wallCollision)
    29.     {
    30.         collidedWithWall = wallCollision;
    31.     }
    32.  
    33.     public bool isCollidingWithWall()
    34.     {
    35.         return collidedWithWall;
    36.     }
    37.  
    38.     public void changeHorizontalDirection()
    39.     {
    40.         invaderHorizontalVelocity.x = -invaderHorizontalVelocity.x;
    41.     }
    42.  
    43.     public void reduceMovementDelay(float reduceAmount)
    44.     {
    45.         movementDelay -= reduceAmount;
    46.     }
    47.  
    48.     public bool canMove(float timePassed)
    49.     {
    50.         return timePassed > movementDelay;
    51.     }
    52. }
    53.  
    EnemyMovement Script

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class EnemyMovement : MonoBehaviour
    5. {
    6.     private EnemyController enemyController;
    7.  
    8.     private Animator invaderAnimator;
    9.  
    10.     public readonly string[] INVADER_TRIGGERS = {"GoToMovement2", "GoToMovement1"};
    11.  
    12.     private float timePassed = 0.0f;
    13.  
    14.     private int animationIndex;
    15.  
    16.     void Start()
    17.     {
    18.         GameObject enemyControllerObject = GameObject.FindWithTag("EnemyController");
    19.  
    20.         if (enemyControllerObject != null)
    21.         {
    22.             enemyController = enemyControllerObject.GetComponent<EnemyController>();
    23.         }
    24.  
    25.         if (enemyControllerObject == null)
    26.         {
    27.             Debug.Log("Could not find EnemyController Object.");
    28.         }
    29.  
    30.         invaderAnimator = GetComponent<Animator>();
    31.         animationIndex = 0;
    32.     }
    33.  
    34.     void Update()
    35.     {
    36.         timePassed += Time.deltaTime;
    37.         if (enemyController.canMove(timePassed) && !isDead())
    38.         {
    39.             setAnimationTrigger();
    40.  
    41.          
    42.             if(!enemyController.isCollidingWithWall())
    43.                 transform.position += enemyController.invaderHorizontalVelocity;
    44.             else
    45.             {
    46.                 enemyController.moveDown();
    47.                 enemyController.changeHorizontalDirection();
    48.                 transform.position += enemyController.invaderHorizontalVelocity;
    49.                 enemyController.setCollidingWithWall(false);
    50.             }
    51.             timePassed = 0.0f;
    52.         }
    53.  
    54.         if(isDead())
    55.         {
    56.             enemyController.reduceMovementDelay(0.0025f);
    57.         }
    58.     }
    59.  
    60.     private bool isDead()
    61.     {
    62.         return invaderAnimator.GetBool("InvaderDies");
    63.     }
    64.  
    65.     private void setAnimationTrigger()
    66.     {
    67.         invaderAnimator.SetTrigger(INVADER_TRIGGERS[animationIndex]);
    68.         animationIndex++;
    69.         animationIndex %= INVADER_TRIGGERS.Length;
    70.     }
    71.  
    72.     void OnTriggerEnter2D(Collider2D collision)
    73.     {
    74.         if (collision.gameObject.tag == "WestWall" || collision.gameObject.tag == "EastWall")
    75.         {
    76.             enemyController.setCollidingWithWall(true);
    77.         }
    78.     }
    79. }
    80.  
     
  2. Deathslice

    Deathslice

    Joined:
    Jan 21, 2017
    Posts:
    24
    After reading the forums for quite a while on this issue, many have suggests to change the collision detection of my invaders from discrete to continuous and that did not work. Just so you know all three of my invaders are in kinematic mode with their own box2D collider and the walls are simply static colliders with only a box2D collider that has isTrigger enabled.
     
  3. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    241
    If you have entities that are moving fast enough that their start and end points are far enough apart that there's empty space in between, then you will miss collisions.

    Try using capsules that wrap around the start and end points. That way, you won't miss any collisions.
     
  4. Deathslice

    Deathslice

    Joined:
    Jan 21, 2017
    Posts:
    24
    And why I can't I do that with the box2D collider that my invader Entity has? Is the capsule collider really the only solution to this?
     
  5. Carwashh

    Carwashh

    Joined:
    Jul 28, 2012
    Posts:
    194
    Use FixedUpdate() (non-frame dependant) instead of Update() (frame dependant)
     
  6. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    284
    Make the colliders bigger? And reposition on collision detection to side of the collider. I don't really use The collision system but if you know the maximum speed, you know how much distance they would cover in an update / fixed update and if your collider is smaller I assume it would get past it (I think this is where continuous should actually help, if I understand it right)

    But in your case, I would just compare their x position to the border coordinates and once they are past those, change their direction. No collider needed.
     
  7. Deathslice

    Deathslice

    Joined:
    Jan 21, 2017
    Posts:
    24
    The colliders take up the entire left and right edge of the screen so I don't think making it bigger is going to help.
    The reason I used colliders was simply so that I do not have to constantly check if the invader has collided with the edge of the screen.
     
  8. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    284
    It was only an idea with the collider size (assume you use a box collider covering the full screen height and then giving it a width that is meaningful)

    You can constantly check the invader xpos - the collider would do exactly the same (just more complex, as it needs to check for box collisions)
     
  9. Deathslice

    Deathslice

    Joined:
    Jan 21, 2017
    Posts:
    24
    I changed all the movement for the players, bullets and invaders into a fixedupdate() function and instead of using transform.Translate, I used rigidbody2D.movePosition for all of them as well and doing all of that did not eliminate my problem. Maybe I should try continuous collision detection again on all of my invaders.
     
  10. Deathslice

    Deathslice

    Joined:
    Jan 21, 2017
    Posts:
    24
    So changing the detection of all 3 invaders to continuous while changing their position using the movePosition instead of the transform.Translate, which unity does not recommended if your object has a rigidbody2D with kinematic enabled, yielded no difference in my results. I then resorted to fiddling around with the physics 2D settings, specifically velocity iterations(it;s default value was 8 and now is 100) and position iterations(it's default value is 3 and now it's 100) and still nothing changed. I'm at a lost at what I can possibly do next.

    This is how my two scripts look now

    EnemyController Script

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class EnemyController : MonoBehaviour
    5. {
    6.     private GameController gameController;
    7.  
    8.     private EnemyMovement [] invaderMovementScripts;
    9.     private EnemyShoot[] invaderShootingScripts;
    10.  
    11.     private Vector2 invaderHorizontalVelocity = new Vector2(0.3f, 0);
    12.     private readonly Vector2 INVADER_VERTICAL_VELOCITY = new Vector2(0, -1.0f);
    13.  
    14.     private AudioSource enemySoundSource;
    15.     public AudioClip[] movementSoundEffectClips;
    16.  
    17.     private float maximumShootWaitTime;
    18.     private float currentAcceptedShotRoll;
    19.     private readonly float MAXIMUM_ACCEPTED_SHOT_ROLL = 0.5f;
    20.     private float currentSightDistance;
    21.  
    22.     private float reduceShootWaitTimeAmount;
    23.     private float amountToIncreaseShotPercentageBy;
    24.  
    25.     private float timePassed;
    26.  
    27.     private float movementDelay;
    28.     private float reduceMovementDelayAmount;
    29.  
    30.     private bool collidedWithWall;
    31.  
    32.     private int soundClipIndex;
    33.  
    34.     void Start()
    35.     {
    36.         gameController = GameObject.FindWithTag("GameController").GetComponent<GameController>();
    37.         invaderMovementScripts = (EnemyMovement[])FindObjectsOfType(typeof(EnemyMovement));
    38.         invaderShootingScripts = (EnemyShoot[])FindObjectsOfType(typeof(EnemyShoot));
    39.         enemySoundSource = GetComponent<AudioSource>();
    40.  
    41.         movementDelay = 1.0f;
    42.         maximumShootWaitTime = 7.0f;
    43.         currentAcceptedShotRoll = 0.1f;
    44.         currentSightDistance = 5.0f;
    45.  
    46.         timePassed = 0.0f;
    47.         soundClipIndex = 0;
    48.  
    49.         collidedWithWall = false;
    50.  
    51.         reduceMovementDelayAmount = 1.0f / gameController.getTotalEnemies();
    52.         reduceShootWaitTimeAmount = (maximumShootWaitTime - 1.0f) / gameController.getTotalEnemies();
    53.         amountToIncreaseShotPercentageBy = (MAXIMUM_ACCEPTED_SHOT_ROLL - currentAcceptedShotRoll) / gameController.getTotalEnemies();
    54.  
    55.         foreach (EnemyShoot invader in invaderShootingScripts)
    56.         {
    57.             invader.randomizeShootTime(maximumShootWaitTime);
    58.         }
    59.     }
    60.  
    61.     void FixedUpdate()
    62.     {
    63.         timePassed += Time.fixedDeltaTime;
    64.  
    65.         if(canMove() && !gameController.areAllEnemiesDead())
    66.         {
    67.             shootPlayer(timePassed);
    68.  
    69.             moveAllActiveInvaders(invaderHorizontalVelocity, timePassed);
    70.             playMovementSoundEffect();
    71.  
    72.             if (collidedWithWall)
    73.             {
    74.                 moveAllActiveInvaders(INVADER_VERTICAL_VELOCITY, timePassed);
    75.                 changeHorizontalDirection();
    76.                 collidedWithWall = false;
    77.             }
    78.  
    79.             timePassed = 0.0f;
    80.         }
    81.     }
    82.  
    83.     private void moveAllActiveInvaders(Vector2 movementVector, float timePassed)
    84.     {
    85.         foreach (EnemyMovement invader in invaderMovementScripts)
    86.         {
    87.             if (invader.isActiveAndEnabled)
    88.             {
    89.                 invader.move(movementVector, timePassed);
    90.             }
    91.         }
    92.     }
    93.  
    94.     private void shootPlayer(float timePassed)
    95.     {
    96.         foreach (EnemyShoot invader in invaderShootingScripts)
    97.         {
    98.             if(invader.isActiveAndEnabled)
    99.             {
    100.                 invader.incrementTimePassed(timePassed);
    101.  
    102.                 if (invader.canShot())
    103.                 {
    104.                     invader.shoot(currentAcceptedShotRoll, currentSightDistance);
    105.                     invader.resetShotTime();
    106.                     invader.randomizeShootTime(maximumShootWaitTime);
    107.                 }
    108.             }
    109.         }
    110.     }
    111.  
    112.     private void playMovementSoundEffect()
    113.     {
    114.         enemySoundSource.PlayOneShot(movementSoundEffectClips[soundClipIndex]);
    115.         soundClipIndex++;
    116.         soundClipIndex %= movementSoundEffectClips.Length;
    117.     }
    118.  
    119.     public void setCollidingWithWall(bool wallCollision)
    120.     {
    121.         collidedWithWall = wallCollision;
    122.     }
    123.  
    124.     public bool isCollidingWithWall()
    125.     {
    126.         return collidedWithWall;
    127.     }
    128.  
    129.     public void changeHorizontalDirection()
    130.     {
    131.         invaderHorizontalVelocity.x = -invaderHorizontalVelocity.x;
    132.     }
    133.  
    134.     public void reduceEnemyConstraints()
    135.     {
    136.         movementDelay -= reduceMovementDelayAmount;
    137.         currentAcceptedShotRoll += amountToIncreaseShotPercentageBy;
    138.         maximumShootWaitTime -= reduceShootWaitTimeAmount;
    139.  
    140.         if(gameController.getTotalEnemies() % gameController.getNumberOfEnemiesPerColumn() == 0)
    141.         {
    142.             currentSightDistance += 1.0f;
    143.         }
    144.     }
    145.  
    146.     public void restoreInitialState()
    147.     {
    148.         movementDelay = 1.0f;
    149.         maximumShootWaitTime = 7.0f;
    150.         currentAcceptedShotRoll = 0.1f;
    151.         currentSightDistance = 5.0f;
    152.  
    153.         soundClipIndex = 0;
    154.         timePassed = 0.0f;
    155.  
    156.         collidedWithWall = false;
    157.  
    158.         reduceMovementDelayAmount = 1.0f / gameController.getTotalEnemies();
    159.         reduceShootWaitTimeAmount = (maximumShootWaitTime - 1.0f) / gameController.getTotalEnemies();
    160.         amountToIncreaseShotPercentageBy = (MAXIMUM_ACCEPTED_SHOT_ROLL - currentAcceptedShotRoll) / gameController.getTotalEnemies();
    161.  
    162.         foreach (EnemyShoot invader in invaderShootingScripts)
    163.         {
    164.             invader.resetShotTime();
    165.             invader.randomizeShootTime(maximumShootWaitTime);
    166.         }
    167.  
    168.         foreach (EnemyMovement invader in invaderMovementScripts)
    169.         {
    170.             invader.resetToInitialAnimationState();
    171.             invader.resetToInitialEnemyLayer();
    172.         }
    173.     }
    174.  
    175.     public bool canMove()
    176.     {
    177.         return timePassed > movementDelay;
    178.     }
    179. }
    180.  
    EnemyMovement script

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class EnemyMovement : MonoBehaviour
    5. {
    6.     private EnemyController enemyController;
    7.  
    8.     private Rigidbody2D enemyRigidbody2D;
    9.  
    10.     private Animator invaderAnimator;
    11.  
    12.     private readonly string[] INVADER_TRIGGERS = {"GoToMovement2", "GoToMovement1"};
    13.  
    14.     private int animationIndex;
    15.  
    16.     private readonly int ALIVE_ENEMY_LAYER = 9;
    17.  
    18.     void Start()
    19.     {
    20.         animationIndex = 0;
    21.         enemyController = GameObject.FindWithTag("EnemyController").GetComponent<EnemyController>();
    22.         enemyRigidbody2D = GetComponent<Rigidbody2D>();
    23.         invaderAnimator = GetComponent<Animator>();
    24.     }
    25.  
    26.     public void move(Vector2 movementVector, float timePassed)
    27.     {
    28.         if (!isDead())
    29.         {
    30.             setAnimationTrigger();
    31.             enemyRigidbody2D.MovePosition(enemyRigidbody2D.position + movementVector * timePassed);
    32.         }
    33.     }
    34.  
    35.     private bool isDead()
    36.     {
    37.         return invaderAnimator.GetBool("InvaderDies");
    38.     }
    39.  
    40.     private void setAnimationTrigger()
    41.     {
    42.         invaderAnimator.SetTrigger(INVADER_TRIGGERS[animationIndex]);
    43.         animationIndex++;
    44.         animationIndex %= INVADER_TRIGGERS.Length;
    45.     }
    46.  
    47.     public void resetToInitialAnimationState()
    48.     {
    49.         animationIndex = 0;
    50.     }
    51.  
    52.     public void resetToInitialEnemyLayer()
    53.     {
    54.         gameObject.layer = ALIVE_ENEMY_LAYER;
    55.     }
    56.  
    57.  
    58.    void OnTriggerEnter2D(Collider2D collision)
    59.     {
    60.         if (collision.gameObject.tag == "Wall")
    61.         {
    62.             enemyController.setCollidingWithWall(true);
    63.         }
    64.     }
    65.  
     
    Last edited: Mar 24, 2017
  11. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    284
    I have to admit that I am not looking at your code when trying to help...so can't offer a specific solution to your implementation.

    Search the forum for @Arowx and @GarBenjamin they both published their source to an invader clone and used different approaches, have a look at how they have done it and see if it helps you?
     
  12. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    5,620
    You can make the colliders wider, allowing for faster moving invaders.

    Or you can just hard code a maximum and minimum x position (assuming they move in the x axis).
     
  13. Deathslice

    Deathslice

    Joined:
    Jan 21, 2017
    Posts:
    24
    Well after comparing state of the static colliders on the scene and game screen before and after the invader collides with either one of them, what I find out is that the colliders get disabled after one of the invaders come into the contact with the static colliders. Why is this the case? No where in the code am I intentionally disabling the left and right wall collider. This is is the case even if the invader goes slow. At the very least, I've now found the root of the problem.
     
  14. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    5,620
    Check the settings of the colliders, you seem to have the OnTriggerEnter2D on the Invaders, do the invaders have a Trigger Collider (collider with is trigger flag set) as this is the only way this event is triggered?

    Or if you have lots of invaders and a single EnemyMovement on a root object then invaders could be receiving the OnTriggerEnter2D() event before the EnemyMovement object.

    Have you tried putting a dedicated script with the OnTriggerEnter2D on the side trigger wall colliders with a link to the invaders EnemyMovement (root object) so they can call enemyController.setCollidingWithWall(true); when something enters them.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class Wall : MonoBehaviour
    5. {
    6.  public EnemyController enemyController;
    7.  
    8.  void OnTriggerEnter2D(Collider2D collision)
    9.  {
    10.    enemyController.setCollidingWithWall(true);
    11.  }
    12. }
    Also to check if events are being called Debug.Log("HitWall"); is handy, as it helps you find out what is and is not happening.
     
  15. Deathslice

    Deathslice

    Joined:
    Jan 21, 2017
    Posts:
    24
    What I have is a single enemyController object(this object has no childs) that controls the movement for each object through the script EnemyController, goes through each enemymovement script and moves each invader accordingly. Each invader has a box collider2D isTrigger disabled and a kinematic rigidbody2D. Both static box colliders only have one component; a box2D collider with isTrigger enabled. I've been thinking of just giving each side colliders a script that checks if the invader has collided with it so I might end up doing just that.
     
  16. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    5,620
    There's your problem you are waiting for an OnTriggerEvent from your invaders that will never be sent. You only receive the events when you put your scripts on objects with Trigger Colliders enabled.

    Good idea as it will let your invaders have a normal collider that can receive hit events from the players shots.
     
  17. Deathslice

    Deathslice

    Joined:
    Jan 21, 2017
    Posts:
    24
    Well I've given the left and right side collider this script

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class DetectInvaderCollision : MonoBehaviour
    5. {
    6.     private EnemyController enemyController;
    7.  
    8.     // Use this for initialization
    9.     void Start ()
    10.     {
    11.         enemyController = GameObject.FindWithTag("EnemyController").GetComponent<EnemyController>();
    12.     }
    13.  
    14.     void OnTriggerEnter2D(Collider2D collision)
    15.     {
    16.         if (collision.gameObject.tag == "Invader")
    17.         {
    18.             enemyController.setCollidingWithWall(true);
    19.         }
    20.     }
    21. }
    22.  
    The colliders still disable themselves after the invader collides with the left or right side wall collider. I thinking that both wall colliders need a static rigidbody2D because the unity documentation specifies that trigger events are only sent if one of the colliders also has a rigidbody attached. So I'm going to try that.

    Edit:

    Nope that did not help.
     
    Last edited: Mar 24, 2017
  18. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    5,620
    Have you tried putting in debug lines to see what is or is not happening (see below) For triggers to work they need to have colliders with the trigger check box ticked.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class DetectInvaderCollision : MonoBehaviour
    5. {
    6.     private EnemyController enemyController;
    7.  
    8.     // Use this for initialization
    9.     void Start ()
    10.     {
    11.         enemyController = GameObject.FindWithTag("EnemyController").GetComponent<EnemyController>();
    12.  
    13.         if (enemyController) Debug.Log("Yay found the controller");
    14.         else Debug.Log("Not found the controller");
    15.     }
    16.  
    17.     void OnTriggerEnter2D(Collider2D collision)
    18.     {
    19.         Debug.Log("Something hit the wall!");
    20.         //if (collision.gameObject.tag == "Invader") // should not be needed
    21.         //{
    22.             enemyController.setCollidingWithWall(true);
    23.         //}
    24.     }
    25. }
    26.  
     
  19. Deathslice

    Deathslice

    Joined:
    Jan 21, 2017
    Posts:
    24
    From the debug log, what I got was "Yay found the controller" and "Something hit the wall!". So the colliders are working but only once. The reason I know this is because when I run the simulation, I switch to the scene screen and carefully watch the right most collider since that is the one the invaders hit first. What happens is the object suddenly deactivates upon contact with the invaders and the green lines around the object disappears(the collision lines I guess).
     
  20. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    284
    Then you very likely deactivate them in code. Try to use debug as arowx suggested. I would add it to any line where you set something to false. Debug log the object you set to false.

    Also if you select the object with the collider and watch it during play in the inspector, does the collider get deactivated? Unticked?
     
  21. Deathslice

    Deathslice

    Joined:
    Jan 21, 2017
    Posts:
    24
    Yes it does get unticked upon contact with the wall collider. I will report back once I find the culprit.

    Edit:

    I found the culprit.

    Look at this script where it disables the invader upon contact.

    DisableInvader

    Code (CSharp):
    1.  
    2.  
    3. using System.Collections;
    4. using UnityEngine;
    5.  
    6. public class DisableInvader : MonoBehaviour
    7. {
    8.     private GameController gameController;
    9.     private EnemyController enemyController;
    10.  
    11.     private Animator animator;
    12.  
    13.     private AudioSource deadClipSource;
    14.  
    15.     public AudioClip deadClip;
    16.  
    17.     public readonly int DEAD_ENEMY_LAYER = 10;
    18.  
    19.     void Start()
    20.     {
    21.         gameController = GameObject.FindWithTag("GameController").GetComponent<GameController>();
    22.         enemyController = GameObject.FindWithTag("EnemyController").GetComponent<EnemyController>();
    23.         animator = GetComponent<Animator>();
    24.         deadClipSource = GetComponent<AudioSource>();
    25.     }
    26.  
    27.     void OnTriggerEnter2D(Collider2D collision)
    28.     {
    29.         if (collision.gameObject.tag == "PlayerMissile")
    30.         {
    31.             gameObject.layer = DEAD_ENEMY_LAYER;
    32.             StartCoroutine(disableInvader(gameObject, "InvaderDies", 0.2f));
    33.             gameController.addScore(gameObject.name);
    34.             gameController.decrementEnemyCount();
    35.             enemyController.reduceEnemyConstraints();
    36.         }
    37.  
    38.         collision.gameObject.SetActive(false); // here is the culprit
    39.  
    40.         if (gameController.areAllEnemiesDead())
    41.         {
    42.             gameController.startNextWave();
    43.         }
    44.     }
    45.  
    46.     IEnumerator disableInvader(GameObject objectToDisable, string animationDeathTransition, float duration)
    47.     {
    48.         animator.SetBool(animationDeathTransition, true);
    49.         deadClipSource.PlayOneShot(deadClip);
    50.         yield return new WaitForSeconds(duration);
    51.         objectToDisable.SetActive(false);
    52.     }
    53. }
    54.  
    If the invader collides with the wall collider it deactiviates regardless who it is. Now I feel like a noob :). Anyways, should I enable the isTrigger button on my invaders seeing that I'm using the onTriggerEnter2D function here(though it still works without it for some reason)?
     
    Last edited: Mar 25, 2017
  22. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    5,620
    Good work.

    A trigger is a physics switch, colliders are things that bounce off or hit each other. Your walls work like a trigger, which is fine.

    Your invaders I would say should not be Triggers, they should be colliders (isTrigger unticked) as you can get contacts from OnCollisionEnter2D() (I think).

    Tip don't turn off other objects features you should inform them of the event e.g. use collision.gameObject.GetComponent<Bullet>().Pop(). Then they can do more interesting stuff and you won't end up with bugs like this one.
     
  23. Deathslice

    Deathslice

    Joined:
    Jan 21, 2017
    Posts:
    24
    Well, I tried to use onCollisionEnter2D but it seems like that it doesn't work on kinematic rigidBody2D objects which is what my invaders are(I'm now talking about when my bullet hits the invader).
     
  24. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    5,620
    OnCollisionEnter2D() watch out for typos, check the API Docs(https://docs.unity3d.com/ScriptReference/Collider2D.OnCollisionEnter2D.html) and Debug.Log("Something Hit Me Collider, Ouch!") is your friend.

    Good Luck!