Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

OnTriggerStay2D

Discussion in '2D' started by lolmonkeyplayer, Nov 4, 2020.

  1. lolmonkeyplayer

    lolmonkeyplayer

    Joined:
    Sep 24, 2020
    Posts:
    5
    My turrets have some strange behaviour in situations like in below photo. I guess this happens because my turret rotates first to bottom enemy and after to second enemy and loop continues.
    upload_2020-11-4_13-51-47.png

    So, my ideea is:
    1) The enemies in turret range will be stored in an array
    2) Every enemy which exit the turret range will be removed from the array
    3) The turret `brain` or rotation is triggered in Update function. It will check from index 0 to index 20. When it finds the first indexed which is NOT null, then it rotates and break so it wont rotate to the next enemy which is in the turret range (aka indexed in our array)

    It relatively works, i mean it really works. At some point, when Unity triggers me an error like in the below photo and the turret doesn't rotate anymore. This happens only to some turrets. Every turret has his own script.
    upload_2020-11-4_13-52-10.png

    I'm just lost, idk what to do/think and i wasted already 4 hours on this crap.

    Here are my scripts:

    The error comes from this function.
    Code (csharp):
    1.  
    2.     private void OnTriggerExit2D(Collider2D collision)
    3.     {
    4.         if (collision.gameObject.CompareTag("Enemy"))
    5.         {
    6.             int ArrayIndex = Array.IndexOf(triggeredEnemies, collision);
    7.             if (ArrayIndex != -1)
    8.             {
    9.                 if (triggeredEnemies[ArrayIndex] != null)
    10.                     triggeredEnemies[ArrayIndex] = null;
    11.                 enemiesInArray--;
    12.             }
    13.         }
    14.     }
    15.  
    Code (csharp):
    1.  
    2.     private void OnTriggerEnter2D(Collider2D collision)
    3.     {
    4.         if (collision.gameObject.CompareTag("Enemy"))
    5.             triggeredEnemies[enemiesInArray++] = collision;
    6.     }
    7.  
    Code (csharp):
    1.  
    2.     Collider2D[] triggeredEnemies = new Collider2D[20];
    3.     public int enemiesInArray = 0;
    4.  
    5.     void Update()
    6.     {
    7.         for (int i = 0; i < 20; i++)
    8.         {
    9.             if (triggeredEnemies[i] != null)
    10.             {
    11.                 Vector3 enemyPosition = triggeredEnemies[i].transform.position;
    12.                 Vector3 vectorToTarget = (enemyPosition - transform.position).normalized;
    13.                 float Angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
    14.                 Quaternion quaternion = Quaternion.AngleAxis(Angle, Vector3.forward);
    15.                 lerpPercent = Mathf.MoveTowards(lerpPercent, 1f, Time.deltaTime * 1.35f);
    16.                 transform.rotation = Quaternion.Slerp(transform.rotation, quaternion, Time.deltaTime * RotationSpeed);
    17.                 if (lerpPercent >= 0.8f)
    18.                     inVision = true;
    19.                 break;
    20.             }
    21.         }
    22.     }
    23.  
     

    Attached Files:

  2. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,345
    You should throw in some Debug.Logs within your OnTriggerEnter and Exit functions to show the index of the array or how big/small the array gets. The error you are getting is telling you the Index is outside the Array bounds, Aka it is either larger than 20 or less than 0. The Debug.Logs will help you see how they are entering/exiting your array and should give you an idea of what is going on.
     
  3. lolmonkeyplayer

    lolmonkeyplayer

    Joined:
    Sep 24, 2020
    Posts:
    5
    The problem is whenever an enemy is getting destroyed, enemiesInArray won't be decreased by 1 because onTriggerExit won't know it actually exited the trigger. But still, my main problem isn't really solved, I managed to somehow reduce the `unwanted behaviour` by creating an child with another trigger function like in the below photo:

    upload_2020-11-4_17-2-16.png

    When the rectangle triggers an enemy,the circle collider will be deactivated and the rotation will be depending on what that rectangle collides with. When this collides with nothing, then circle collider will be again activated.

    But still, my turrets are flickering fast sometimes, and i really don't know why. Maybe my rotation function is bad?
     
  4. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,345
    You didnt mention a flicker issue originally so Im not sure with that. Glad you got the array issue fixed. If it is flickering than it probably is something wrong with the turret rotation. I havent worked with rotations like that much but maybe you could turn your rotation script into a State Machine and have various states like Idle, FoundEnemy, ShootingEnemy, etc. I like using state machines mainly because it breaks down behavior into small sections where it is easy to figure out what is happening when and easier to debug, but thats my opinion.

    I know there are tons of turret defense videos out there so maybe watch a different one and see how they handle rotation before you try my suggestion.
     
    lolmonkeyplayer likes this.
  5. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Just use a List instead of an array to add/remove Collider2D references as they enter/exit the turret's collider.
    Code (CSharp):
    1. List<Collider2D> triggeredEnemies = new List<Collider2D>();
    2.  
    3. void OnTriggerEnter2D(Collider2D collider){
    4.    if(collider.gameObject.CompareTag("Enemy")) {
    5.       triggeredEnemies.Add(collider);
    6.    }
    7. }
    8.  
    9. void OnTriggerExit2D(Collider2D collider){
    10.    if(collider.gameObject.CompareTag("Enemy")) {
    11.       triggeredEnemies.Remove(collider);
    12.    }
    13. }