Search Unity

OnTriggerEnter is called twice sometimes

Discussion in 'Scripting' started by ammar26, Jul 2, 2011.

Thread Status:
Not open for further replies.
  1. ammar26

    ammar26

    Joined:
    Jun 5, 2011
    Posts:
    29
    Sometimes my OnTriggerEnter() is called twice. I have a variable that increment points each time when laser object collides. Sometimes i get double points on one collision. Does any one know whats the problem
    Code (csharp):
    1.  
    2. void OnTriggerEnter(Collider col)
    3.     {
    4.         if(col.gameObject.tag == "Laser")
    5.         {
    6.             Points++;
    7.                 }
    8.          }
    9.  
     
  2. MrBlading4ever

    MrBlading4ever

    Joined:
    Jul 2, 2011
    Posts:
    6
    try "OnTriggerExit"
     
    the_nem_s likes this.
  3. ammar26

    ammar26

    Joined:
    Jun 5, 2011
    Posts:
    29
    Thanks .... Its working
     
  4. nomadic

    nomadic

    Joined:
    Mar 4, 2010
    Posts:
    44
    How would I apply OnTriggerExit exactly? I'm having the same problem, but I'm not sure how the trigger exit would help since I want to detect when my objects first collide.
     
  5. thesimi

    thesimi

    Joined:
    Jun 16, 2009
    Posts:
    94
    I don't know if I understood that correctly, but:

    OnTriggerEnter:
    Code (csharp):
    1.  
    2. function OnTriggerEnter () {
    3. //Some stuff goes here
    4. }
    5.  
    OnTriggerExit:
    Code (csharp):
    1.  
    2. function OnTriggerExit () {
    3. //Some stuff goes here
    4. }
    5.  
    hope that helps :D
     
  6. nomadic

    nomadic

    Joined:
    Mar 4, 2010
    Posts:
    44
    Well thanks for the reply, but I need a little more help than that :)

    I understand how the OnTrigger functions work and how to use them. But OnTriggerEnter is being called exactly twice and causing problems. I'm not sure how OnTriggerExit can help because it won't be called at the correct time, nor will it stop OnTriggerEnter from firing twice.
     
  7. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    I recently discovered a bug where 2 bullets could enter the collider in the same frame, triggering OnTriggerEnter twice and messing up my enemy count. I solved it this way:

    Code (csharp):
    1. private var hitpoints = 1;
    2.  
    3. function OnTriggerEnter (hit : Collider)
    4. {
    5.     if (hit.gameObject.tag == "bullet")
    6.     {
    7.         hitpoints --;
    8.         if (hitpoints > -1)
    9.         {
    10.             // do stuff
    11.         }
    12.     }  
    13. }
     
  8. nomadic

    nomadic

    Joined:
    Mar 4, 2010
    Posts:
    44
    Whew, I think I figured out my problem! :eek: I was already making sure to disable my colliding object's trigger as soon as it hit the player (just in case), but I completely overlooked that the collider on the player had isTrigger enabled.

    I knew it had to be something silly like that and not a scripting error. Still not quite sure why my player object's collider should be able to call OnTriggerEnter on its own collider, but at least it's solved!
     
    AssassinSquid and BurakKorkmaz16 like this.
  9. ASMach

    ASMach

    Joined:
    Nov 26, 2011
    Posts:
    43
    I have a similar problem: even though I have a boolean flag that gets set as soon as OnTriggerEnter() gets called, OnTriggerEnter() still gets called twice and exactly twice, even if it's set to only interact with one collier:

    Code (csharp):
    1.  
    2. //Checkpoint.js
    3.  
    4. #pragma strict
    5.  
    6. private var levelManager : GameObject;
    7.  
    8. private var engine : GameObject;
    9.  
    10. private var passed = false;
    11.  
    12. var checkpointSound : AudioClip;
    13.  
    14. function Start ()
    15. {
    16.  
    17.     levelManager = GameObject.FindWithTag("LevelManager");
    18.     engine = GameObject.FindWithTag("Jetpack");
    19.  
    20. }
    21.  
    22. function Update ()
    23. {
    24.      transform.Rotate(Vector3.forward * 15 * Time.deltaTime);
    25.  
    26. }
    27.  
    28. function OnTriggerEnter (other : Collider)
    29. {
    30.  
    31.     if (!passed)
    32.     {
    33.         if (other == engine.collider)
    34.         {
    35.             passed = true;
    36.             Destroy (gameObject);
    37.            
    38.             Debug.Log("Registering Checkpoint Notification");
    39.             NotificationCenter.DefaultCenter().PostNotification(this, "RegisterCheckpointHit");
    40.             AudioSource.PlayClipAtPoint(checkpointSound, transform.position);
    41.         }
    42.     }
    43. }
    44.  
    It makes sure that the other collider is the collider used for the engine used by my character (and there is only one engine, with only one collider). However, because Checkpoint.js gets called twice, every time a checkpoint is passed, it registers two checkpoints instead of one. This means the player gets twice as much extra time as intended, twice the intended score, and completes two checkpoints at once. This means that the player can pass through the finish point and win with half the checkpoints remaining, since the level manager unlocks the finish point by comparing the number of checkpoints passed by the total number in a level (obtained by iterating through all the objects with the tag "Checkpoint").

    Code (csharp):
    1.  
    2. //LevelStatus.js:
    3.  
    4. var numCheckpoints : int;
    5. var checkpointsHit : int;
    6. var score : int;
    7.  
    8. var gameWon = false;
    9.  
    10. function Start () {
    11.  
    12.     NotificationCenter.DefaultCenter().AddObserver(this, "RegisterCheckpointHit");
    13.     NotificationCenter.DefaultCenter().AddObserver(this, "RegisterWin");
    14.     NotificationCenter.DefaultCenter().AddObserver(this, "AddScore");
    15.  
    16.     var checkpointsArray : GameObject[];
    17.     checkpointsArray = GameObject.FindGameObjectsWithTag("Checkpoint");
    18.    
    19.     checkpointsHit = 0;
    20.     score = 0;
    21.    
    22.     numCheckpoints = checkpointsArray.Length;
    23. }
    24.  
    25. function RegisterCheckpointHit()
    26. {
    27. if (checkpointsHit < numCheckpoints)
    28. {
    29.     checkpointsHit++;
    30.    
    31.     score += 5000;
    32. }
    33.  
    34. if (checkpointsHit > numCheckpoints)
    35. {
    36.     checkpointsHit = numCheckpoints;
    37. }
    38.  
    39. if (checkpointsHit == numCheckpoints)
    40. {
    41.     NotificationCenter.DefaultCenter().PostNotification(this, "ActivateFinishLoop");
    42.    
    43.     score += 10000;
    44. }
    45.  
    46. Debug.Log("Checkpoint Hit");
    47. }
    48.  
    49. ...
    50.  
    I have a similar issue with picking up items. Whenever a gem is picked up, the player gets twice the intended score:

    Code (csharp):
    1.  
    2. //GemPickup.js
    3.  
    4. #pragma strict
    5.  
    6. var scoreValue : int = 1;
    7.  
    8.  
    9. private var pickedUp = false;
    10.  
    11.  
    12. var pickupSound : AudioClip;
    13.  
    14. function OnTriggerEnter (other : Collider) {
    15.     pickedUp = true;
    16.    
    17.     Debug.Log("Add score");
    18.     NotificationCenter.DefaultCenter().PostNotification(this, "AddScore", scoreValue);
    19.            
    20.         AudioSource.PlayClipAtPoint(pickupSound, transform.position);
    21.        
    22.         NotificationCenter.DefaultCenter().PostNotification(this, "AddScore", scoreValue);
    23.        
    24.         Destroy(gameObject);
    25. }
    26.  
    Since the boolean values that store whether or not an item was picked up are the first things to be set in my code, I can't understand why OnTriggerEnter() would be called twice.

    MachCUBED
     
  10. Tobias J.

    Tobias J.

    Joined:
    Feb 21, 2012
    Posts:
    423
    Have you tried checking what those two collisions are, in terms of gameobject?

    If they are both the character, then the easy solution might be to do it with OnTriggerExit() in stead? I'm guessing maybe that only fires once?

    If they aren't the same, well then perhaps now you know where to look?

    Good luck!
     
  11. ASMach

    ASMach

    Joined:
    Nov 26, 2011
    Posts:
    43
    Changing all instances of OnTriggerEnter() to OnTriggerExit() isn't helping, since it's being triggered twice. Moreover, it has to be OnTriggerEnter() because otherwise, the game's response feels delayed.

    Edit: I added this code to the OnTriggerEnter() functions in all my code:

    Code (csharp):
    1.  
    2. Debug.Log("Other Collider:" + other.name);
    3.  
    And it turns out that the same collider is calling OnTriggerEnter() twice, which it shouldn't.

    It is true that Player is a mesh with a skeleton as a child, which has several colliders attached to it (one for each bone). There is also a JetpackMount child object, which is a parent of the actual Engine (a large cylindrical mesh with an additional rotor mesh scripted to spin at the speed of the throttle input). Engine (the object) has only one collider, and it's the only collider that interacts with the checkpoints (both through script and layered collisions). The gems can be picked up by any of the player's colliders, but the point is that there are pickup flags on the gems. What's going on?
     
    Last edited: Apr 16, 2012
    xvivax likes this.
  12. burtonposey

    burtonposey

    Joined:
    Sep 8, 2009
    Posts:
    62
    I think the prudent approach is to disable the ability for picked up object to be processed more than once. This way it can be checked for ability to pick up, handled if it can be picked up, skipped if it cannot.

    I'm not saying that is fixing the issue at it's very root, but you won't have this problem again. If the first guy trips a flag that denotes whether or not you can pick up something, then any consecutive attempts will be ignored.
     
  13. ASMach

    ASMach

    Joined:
    Nov 26, 2011
    Posts:
    43
    Oddly enough, I do have boolean flags to prevent my objects (such as checkpoints and items), and here's the code:

    Code (csharp):
    1.  
    2. //Checkpoint.js
    3.  
    4. ...
    5.  
    6. private var passed = false; // Boolean flag
    7.  
    8. ...
    9.  
    10. function OnTriggerEnter (other : Collider)
    11. {
    12.  
    13.     if (!passed) // Don't run the rest of the code if the checkpoint has already been passed.
    14.     {
    15.         if (other == engine.collider) // Only collide with the engine.
    16.         {
    17.             passed = true;
    18.             Destroy (gameObject);
    19.            
    20.             Debug.Log("Other Collider:" + other.name);
    21.             Debug.Log("Registering Checkpoint Notification");
    22.             NotificationCenter.DefaultCenter().PostNotification(this, "RegisterCheckpointHit");
    23.             AudioSource.PlayClipAtPoint(checkpointSound, transform.position);
    24.         }
    25.     }
    26. }
    27.  
    Similarly, I have the same flags on my items:

    Code (csharp):
    1.  
    2. //GemPickup.js
    3.  
    4. #pragma strict
    5.  
    6. var scoreValue : int = 1;
    7.  
    8.  
    9. private var pickedUp = false; //boolean flag
    10.  
    11.  
    12. var pickupSound : AudioClip;
    13.  
    14. function OnTriggerEnter (other : Collider) {
    15.     if (!pickedUp)
    16.     {
    17.         pickedUp = true;
    18.        
    19.         Debug.Log("Gem picked up");
    20.         Debug.Log("Other Collider:" + other.name);
    21.         Debug.Log("Add score:" + scoreValue);
    22.         NotificationCenter.DefaultCenter().PostNotification(this, "AddScore", scoreValue);
    23.            
    24.         AudioSource.PlayClipAtPoint(pickupSound, transform.position);
    25.        
    26.         Destroy(gameObject);
    27.     }
    28. }
    29.  
    Console output when I pass a single checkpoint:

    Code (csharp):
    1.  
    2. Other Collider:Jetpack1
    3. UnityEngine.Debug:Log(Object)
    4. Registering Checkpoint Notification
    5. UnityEngine.Debug:Log(Object)
    6. TIME EXTENDED
    7. UnityEngine.Debug:Log(Object)
    8. Checkpoint Hit
    9. UnityEngine.Debug:Log(Object)
    10. TIME EXTENDED
    11. UnityEngine.Debug:Log(Object)
    12. Checkpoint Hit
    13. UnityEngine.Debug:Log(Object)
    14.  
    And when a gem is picked up:

    Code (csharp):
    1.  
    2. Gem picked up
    3. UnityEngine.Debug:Log(Object)
    4. GemPickup:OnTriggerEnter(Collider) (at Assets/Props/Scripts/GemPickup.js:16)
    5. Other Collider:Jetpack1
    6. UnityEngine.Debug:Log(Object)
    7. Add score:500
    8. UnityEngine.Debug:Log(Object)
    9.  
    The score from the gem is being added once because the trigger is only being triggered once per gem (as expected). However, the checkpoints are being registered twice, even though the trigger is only being triggered once. Perhaps there's some stray code on some other object that has RegisterCheckpointHit as an observer when it shouldn't.
     
  14. burtonposey

    burtonposey

    Joined:
    Sep 8, 2009
    Posts:
    62
    I guess use MonoDevelop and do a File Search in the entire project for "RegisterCheckpointHit" and see if you get more hits than you expected. I don't see an extra register of it in the code you've posted here.

    My gut tells me to write in the Notification Center code (found it via search on Unify) and perhaps add traces in there to show you the object that is sending the message along.

    Another basic question to ask is, "Do you get the same results every time or does the double reporting vary on different objects?"
     
  15. ASMach

    ASMach

    Joined:
    Nov 26, 2011
    Posts:
    43
    Thank you for your help burtonposey,

    Yes, I get the same results all the time. As for MonoDevelop, duing a File Search on the entire project didn't dig up any RegisterCheckpointHit observers that I hadn't already become aware of. Here is RegisterCheckpointHit in HUD.js:

    Code (csharp):
    1.  
    2. ...
    3. function RegisterCheckpointHit ()
    4. {
    5.     endTime += checkpointBonus;
    6.     Debug.Log("TIME EXTENDED");
    7. }
    8.  
    And in LevelStatus.js:

    Code (csharp):
    1.  
    2. function RegisterCheckpointHit()
    3. {
    4. if (checkpointsHit < numCheckpoints)
    5. {
    6.     checkpointsHit += 1;
    7.    
    8.     score += 5000;
    9. }
    10.  
    Both HUD.js and LevelStatus.js are observers of RegisterCheckpoint hit. HUD.js adds extra time to the clock when you pass a checkpoint, but because RegisterCheckpointHit() is being called twice in each instance, the player gets double the time bonus. Similarly, LevelStatus.js increases the number of checkpoints hit by 1 and adds 5,000 points to the player's score. It also has RegisterCheckpointHit being called twice, so the player effectively crosses two checkpoints at once. I have verified that none of the checkpoints have duplicates in the exact same position. It's very strange that while the collider for each checkpoint is being triggered once, RegisterCheckpointWin() is being called twice by both scripts that observe the notification.

    Edit: I changed the name of RegisterCheckpointWin() in HUD.js to ExtendTime(), and changed this:

    Code (csharp):
    1.  
    2. NotificationCenter.DefaultCenter().AddObserver(this, "RegisterCheckpointHit");
    3.  
    to this:

    Code (csharp):
    1.  
    2. NotificationCenter.DefaultCenter().AddObserver(this, "ExtendTime");
    3.  
    This means that only LevelStatus.js gets the RegisterCheckpointHit notification. I modified the code on Checkpoint.js to add this:

    Code (csharp):
    1.  
    2. NotificationCenter.DefaultCenter().PostNotification(this, "ExtendTime");
    3.  
    after this:

    Code (csharp):
    1.  
    2. NotificationCenter.DefaultCenter().PostNotification(this, "RegisterCheckpointHit");
    3.  
    OnTriggerEnter() now looks like this i Checkpoint.js:

    Code (csharp):
    1.  
    2. function OnTriggerEnter (other : Collider)
    3. {
    4.  
    5.     if (!passed)
    6.     {
    7.             passed = true;
    8.             Destroy (gameObject);
    9.            
    10.             Debug.Log("Other Collider:" + other.name);
    11.             Debug.Log("Registering Checkpoint Notification");
    12.             NotificationCenter.DefaultCenter().PostNotification(this, "RegisterCheckpointHit");
    13.             NotificationCenter.DefaultCenter().PostNotification(this, "ExtendTime");
    14.             AudioSource.PlayClipAtPoint(checkpointSound, transform.position);
    15.     }
    16. }
    17.  
    Making the above changes fixed my problem. Moral of the story: be careful when you post a notification and have two different functions of the same name attached to different scripts on different objects.
     
    Last edited: Apr 17, 2012
  16. shotgunemmet

    shotgunemmet

    Joined:
    Apr 17, 2012
    Posts:
    2
    You can sometimes get OnTriggerEnter() called more than once if you have child objects with the same tag and colliders.

    I got that error once because the game object for my player had 2 sphere colliders

    Easy fixes to both ways = remove unwanted collider attributes

    =]
     
  17. theassassinpig

    theassassinpig

    Joined:
    Jul 10, 2012
    Posts:
    1
    you could make it like this...

    function OnTriggerEnter(collider : Collider){
    if(pickedUp == true){
    return;
    }
    pickedUp = true;
    }

    this way, if you pick it up again the funtion will end.
     
  18. jquery404

    jquery404

    Joined:
    May 21, 2012
    Posts:
    16
    I've had the same problem and it did pull my hair out for a while until I find out I've checked IsTrigger for both objects.
    In my game, player ship can fire 2 projectiles together, so when any enemy hits by both projectile then OnTriggerEnter() called 2 times. even though Ive checked

    if(EnemyHealth < 0) {
    Point+=5;
    }

    but didnt help.

    then i unchecked IsTrigger from the projectile as my enemies already got IsTrigger (and player projectile are not hitting with any other object except enemies) so that did the trick.
     
    Last edited: Aug 8, 2012
  19. Ahmed_Mansoor

    Ahmed_Mansoor

    Joined:
    Mar 20, 2013
    Posts:
    2
    OnTriggerEnter is called twice sometimes

    I have the same Problem in Car Racing thats because i have 2 Box colliders for my car, 1 for bottom and other for top part
    thats why OnTriggerEnter was called twice.
     
    ricksto87 and m7uniyal like this.
  20. Ecocide

    Ecocide

    Joined:
    Aug 4, 2011
    Posts:
    293
    I always store the player in a variable at the beginning of runtime like

    Code (csharp):
    1.  
    2. private Transform player;
    3.  
    4. void Start() {
    5. //assigning the player
    6. }
    7.  
    8. void OnTriggerEnter(Collider other){
    9. if(other == player.collider){
    10. //do something
    11.  }
    12. }
    I even made only ONE invisible box right inside the player and assigned that to the transform variable. This way the OnTriggerEnter method will definitely only be called once.
     
  21. Harizio

    Harizio

    Joined:
    May 18, 2014
    Posts:
    1
    I know this is thread is really old, but if someone is getting this problem and trying to find a solution, check if you have both a rigidbody and a collider on the same object. Disabling the collider did the trick for me.
     
    Arnazian, abotrix and xvivax like this.
  22. Amyr

    Amyr

    Joined:
    Sep 21, 2014
    Posts:
    5
    Hy all!

    I have a simillar problem.
    I created a SpaceShipPrefab using Unity primitives (capsules, cubes, etc). One of those primitives is a left wing, the other is the body, another one is the right wing, and so forth.
    This prefab is instatiated by a PlayerContainer prefab, which is never destroyed.
    I do this so I can destroy the ship, animate explosions and respawn the player without losing player script.
    The PlayersScript is attached to PlayerContainer, and the ShipPrefab has no script on it.
    PlayerScript fires the shoot and receives damage and explosion events.
    ShootScript handles the collision, triggering the damage event.

    The problem is that, when a shoot hits, it usually hits more than one ShipPrefab element at a time, triggering the collision multipe times, resulting in very unlikely behavior concerning damage and destruction.

    How could I prevent this from happening?
     
  23. Skizerz

    Skizerz

    Joined:
    Jan 1, 2015
    Posts:
    1
    Old thread i know, but i found the problem! for me anyway

    I had bullets colliding with ships, the ships had a collider and rigid body. both rigidbodies and colliders have an OnTriggerEnter() function, so both were being called at the exact same time on the same frame. so i disabled the collider and voila, only 1 collision per triggerenter
     
  24. kunalxigxag

    kunalxigxag

    Joined:
    Aug 7, 2014
    Posts:
    9
    Thanks Skirez, this solved my issue :)
     
  25. _bimo

    _bimo

    Joined:
    Jul 13, 2015
    Posts:
    1
    you may have double box colliders on your player or laser, i had the same problem though
    (4 years past :p, my life's connexion is a bit laggy xD)
     
    FeniXD likes this.
  26. Sajalsh25

    Sajalsh25

    Joined:
    Jul 14, 2016
    Posts:
    2
    THANKS! :D
     
  27. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Rather pointless Frankensteining this here as you can just "like" a post without bringing it to the top of the forum for everyone to see, but just as a warning: using OnTriggerExit isn't a solution to this problem. If the OnTriggerEnter function is being called twice, it's likely not a bug to work around, but because two collisions are happening, and two collisions happening simultaneously between two objects means that one of them has more than one collider attached.

    If the object with the rigidbody has a collider, and one of its children has a collider, they can both cause a trigger to fire while moving into it. If you need to use "compound colliders" in this way, you'll need to adjust the logic a bit- either set "limb" colliders to a different layer from the torso collider and go into the Layer Collision Matrix and turn off collisions between the limb layer and layers that they don't need to interact with (leaving the "core collider" to handle triggers), or allow the triggers to happen but, in the OnTriggerEnter function, filter out all of the ones that don't belong to a given object tag or layer manually in the code. Something like that.
     
  28. Dakor

    Dakor

    Joined:
    Sep 2, 2013
    Posts:
    7
    Hey, i had the same issue just know and solved it by using a static bool to check if OnTriggerEnter was allready called.
    It did not work with a regular bool, it had to be a static one. It's not a nice and clean solution, but for my prototype it's enough.

    Code (CSharp):
    1. private static bool timeout = false;
    2.  
    3.   void OnTriggerEnter(Collider other)
    4.     {
    5.         if (other.name.Equals("car-normal-red"))
    6.         {
    7.             if (timeout)
    8.             {
    9.                 Debug.Log("Checkpoint hasn't timedout yet");
    10.                 return;
    11.             }
    12.             timeout = true;
    13.             NextPoint();
    14.         }
    15.     }
     
    jacobgeorge26 and n0ksi0210 like this.
  29. DRsabadash

    DRsabadash

    Joined:
    Mar 17, 2017
    Posts:
    1
    For some reason, setting a boolean check for colliders can sometimes cause the boolean value to either flip, or to turn on/off the OnTriggerEnter/OnTriggerExit methods while remaining in the trigger area,
    like opening a door and closing it repeatedly while in the trigger area, or flipping the boolean value so it closes when you approach and opens when you walk away.

    using a simple variable iterator prevents the actual method from being called repeatedly, guaranteeing only one execution per collision.


    Code (CSharp):
    1. //previous code in class
    2.     //using a door opening and closing as an example
    3.     [SerializeField] private GameObject device;
    4.         private int i = 0;
    5.  
    6.  
    7.         void OnTriggerEnter(Collider other){
    8.             DoorScript door = device.GetComponent<DoorScript>();
    9.             if (i == 0) {
    10.                 if (door != null) {
    11.                     door.Operate ();
    12.                     i++;
    13.                 }
    14.             }
    15.  
    16.         }
    17.         void OnTriggerExit(Collider other){
    18.             DoorScript door = device.GetComponent<DoorScript>();
    19.             if (i == 1) {
    20.                 if (door != null) {
    21.                     door.Operate ();
    22.                     i = 0;
    23.                 }
    24.             }
    25.  
    26.         }
    27.     /* All DoorScript contains is a function Operate() and a boolean for if the door is open, and an if/else statement in Operate() for moving door to open if bool is false (set to closed) and moving door to closed if bool is true (set to open) */
    28.  
     
  30. UrbanLollipop

    UrbanLollipop

    Joined:
    Jul 21, 2017
    Posts:
    3
    I had the same problem where killing an enemy gave double points sometimes but not others. I solved it by creating a coroutine that waited before it could add points again.

    Code (CSharp):
    1.     void OnTriggerEnter2D (Collider2D other)
    2.     {
    3.         if (other.tag == "Enemy" && gettingPoints == false)
    4.         {
    5.             Instantiate (enemyDeathEffect, other.transform.position, other.transform.rotation);
    6.             Destroy (other.gameObject);
    7.             StartCoroutine ("PointGetWait");
    8.         }
    9.         Instantiate (impactEffect, transform.position, transform.rotation);
    10.         Destroy (gameObject);
    11.     }
    12.  
    13. public IEnumerator PointGetWait ()
    14.     {
    15.         gettingPoints = true;
    16.         Debug.Log ("Enemy Killed");
    17.         ScoreManager.AddPoints (pointsForKill);
    18.         yield return new WaitForSeconds (pointDelay);
    19.         gettingPoints = false;
    20.     }

    I'm just starting out learning coding, so there might be more efficient ways of doing this, but this worked for my purposes. This is for a 2D platformer but I assume it would work in 3D as well?

    EDIT: Well I'm Stupid. It returns before setting gettingPoints back to false, so it can't be applied more than once, but it's fine in my instance because it's only supposed to activate once before destroying the projectile anyway, but it makes it less applicable to other problems. I guess the entire coroutine could be replaced with
    gettingPoints = true;
    so ignore me.
     
    Last edited: Aug 9, 2017
  31. FeniXD

    FeniXD

    Joined:
    May 16, 2017
    Posts:
    9
    I noticed someone had already said it, but I too had this issue. It is was caused when two box colliders collide. If you have a box collider on the object, and one on the other object that are both triggers, it can cause it to trigger twice.
     
    loveshdongre57 likes this.
  32. Arctic_Evolution

    Arctic_Evolution

    Joined:
    Jan 8, 2018
    Posts:
    65
    i know it seems obvious, sometimes ur stuff has two colliders, like mesh collider and capsule - i was stuck on this for ages with this double trigger.. and i never noticed i had two colliders on all my NPCs
     
  33. 9uile

    9uile

    Joined:
    Mar 11, 2016
    Posts:
    32
    Hi all !
    I have a ship. It fires 2 bullets in front of him. Sometimes, the score is added twice.
    Well, the problem is this *%!!# sometimes occurence at the very same time OnTriggerEnter !!!
    So after looking an answer for a long time, i decided to put the enemy in a fixed position to have always the issue.
    And finally, I found a solution (weird but it works currently regarding my tests).

    Code (CSharp):
    1. private int count;
    Code (CSharp):
    1. if (life <= 0)
    2. {
    3.     if (count == 0)
    4.     {
    5.         while (count <= 0) {count++;} //count value is sure > 0 after this
    6.         AddScoreDestruct();
    7.     }
    8. }
    Give me your feedback if you apply this code in your games !!
     
  34. astracat111

    astracat111

    Joined:
    Sep 21, 2016
    Posts:
    725
    I'm having this same problem, I'm considering a short delay timer in there, as it seems a short delay should stop it from triggering twice in one or two frames. This reminds me of navmesh.setdestination. I had to set a short delay timer for that of 4 frames to make sure it processes.
     
  35. NEVER-SETTLE

    NEVER-SETTLE

    Joined:
    Apr 22, 2018
    Posts:
    30
    I had the same thing happening and I discovered that the object that was colliding with my collider, was having multiple colliders on it and I didn't realize.
     
    Wawa_Wawa likes this.
  36. Savager

    Savager

    Joined:
    Aug 31, 2013
    Posts:
    1
    Thanks!!! I had the same problem with hitting an enemy with a sword and solved it disabling the other bodyparts colliders.
     
  37. venusflytrap

    venusflytrap

    Joined:
    Apr 11, 2019
    Posts:
    1
    I have the same issue....except that the OnTriggerEnter is called exactly 3 times. The gameObject this script is attached has only 1 sphere collider, no rigidbody. It is the child of another gameObject which has 1 sphere collider and rigidbody. The collider on the gameObject with the script has isTrigger enabled, if I disable it then it doesn't trigger. I can't disable isTrigger on the checkpoint because then I can't pass through it. The function is triggered 3 times even if i disable the collider of its parent.
     
  38. ButterJuice

    ButterJuice

    Joined:
    Jul 26, 2019
    Posts:
    1
    Same problem here but my OnTriggerEnter is called 2 time and my OnTriggerExit is called 3/4 time.
     
  39. alexeu

    alexeu

    Joined:
    Jan 24, 2016
    Posts:
    257
    I confirm the issue(?).
    My problem was to play an Audiosource Once and using OnTriggerEnter() made the sound play twice.
    I had to use an integer to compute de triggs number so i play sound only when its aqual to one.
    Works perfectly...
     
  40. alexeu

    alexeu

    Joined:
    Jan 24, 2016
    Posts:
    257
  41. WaqasGameDev

    WaqasGameDev

    Joined:
    Apr 17, 2020
    Posts:
    118
    Hi, May be this can help some one facing issue like me. In my case it turned out that, my player collider was EXITING the trigger collider during animation playing and then was ReEntering the trigger causing the double trigger detection. I checked by Debug.Log command in OnTriggerExit to check if the sequence is as expected i.e. Enter-Exit-Enter and it was exactly like this. So In my case atleast, I could control it by placing a flag some thing like this

    Code (CSharp):
    1. bool triggerCalled = false;
    2. private void OnTriggerEnter(Collider other)
    3. {
    4. if(!triggerCalled){
    5. triggerCalled = true;
    6. //do some stuff
    7. }
    8. }
    9.  
    And this flag worked as expected.
     
    mustafahtp3 likes this.
  42. gizmo928

    gizmo928

    Joined:
    Dec 7, 2017
    Posts:
    1
    I know this is an old post but i was having the same issue as OP! For me it was my character having two colliders. One of them is already on "CharacterController" while i had another capsule collider on my Character. I removed the capsule collider and now OnTriggerEnter() is only called once.
     
  43. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    Google translate for the lazy.
     
  44. FernandoCarvalho

    FernandoCarvalho

    Joined:
    Aug 13, 2018
    Posts:
    1
    TL;DR. My problem was having two colliders at the object, thus being counted twice, I've used parent.GetInstanceId() as unique identifier.

    Hi, i've had a similar problem just want to share how I debuged and solved this issue.
    To debug the problem I've noticed that even by using Debug.log(other.name); the same name was logged twice, so I thought about loggin the instanceId of this object, and noticed that were two different instance ids, I've changed my inspector to debug and noticed two colliders in the object, one normal and other as trigger) and this two colliders was the cause of my problem.
    To solve this I've created a new HashSet<int> and stored the other.parent.GetInstanceId() and to get how many had entered I used the Count function of this hashset.
     
    FoldFence likes this.
  45. entirelydoomed

    entirelydoomed

    Joined:
    Mar 26, 2021
    Posts:
    67
    If someone encounters such problem be aware that setting rigidbody to kinematic or back to non-kinematic reloads all physics interactions so OnTriggerExit is instantly called after the switching and OnTriggerEnter is also called after that.
     
  46. LagSik

    LagSik

    Joined:
    Apr 6, 2020
    Posts:
    5
    Thank a lot for that precision. This helps me solved my problem.
     
Thread Status:
Not open for further replies.