Search Unity

OnTriggerStay calling too late?

Discussion in 'Scripting' started by CoolJosh3k, Sep 24, 2017.

  1. CoolJosh3k

    CoolJosh3k

    Joined:
    Dec 3, 2016
    Posts:
    145
    To try an use colliders instead of rays, I am trying to use OnTriggerStay and OnTriggerExit.

    My issue is that when I do something based on OnTriggerExit, OnTriggerStay seems to run AFTER.

    Basically:
    Code (CSharp):
    1.  
    2. void OnTriggerStay() {
    3.     A = B;
    4. }
    5. void OnTriggerExit() {
    6.     A = C;
    7. }
    8. void FixedUpdate()
    9. {
    10.     Debug.Log(A); // Results in (A == B).
    11. }
    12.  
    Is there some reason and some way to fix this?
     
  2. Rob21894

    Rob21894

    Joined:
    Nov 21, 2013
    Posts:
    309
    What is the gameobject you are checking for? usually OnTrigger functions check for a target object, as shown in the script below, its checking if a gameobject that contains a collider has the tag "Player" and will run the functions based on this.
    Code (CSharp):
    1.     private int a;
    2.     private int b = 10;
    3.     private int c = 5;
    4.  
    5.     void FixedUpdate()
    6.     {
    7.         Debug.Log(a);
    8.     }
    9.  
    10.     void OnTriggerStay(Collider other)
    11.     {
    12.         if (other.tag == "Player")
    13.         {
    14.             a = b;
    15.         }
    16.     }
    17.  
    18.     void OnTriggerExit(Collider other)
    19.     {
    20.         if (other.tag == "Player")
    21.         {
    22.             a = c;
    23.         }
    24.     }
     
  3. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,546
    First of all, if you are trying to avoid raycast because you think they are bad on performance, that is false. Raycasts are bad in performance in the same situations that a Trigger/Collision is, which is situations where a very high polycount mesh or lots of meshes are being collided/cast against constantly.

    In regards to your issue, I think your testing method is at fault here. Put the Debug.Log() into your trigger methods, and you will see that the TriggerExit is the last debug message. At least on 2017.1.1p3 which I am testing with. In fact, even if I use your script, the order is correct.
     
  4. CoolJosh3k

    CoolJosh3k

    Joined:
    Dec 3, 2016
    Posts:
    145
    @Rob:
    Thanks, but I was just writing it that way to it simple. Same issue will result.

    @Invertex:
    Thanks for the tip.
    I would expect those results, yes. The issue is that the order does not work out as I expect. It is as if the code within "stay" is calling after the "exit" stuff. I figured if the exit message is called, then the stay won't be called since it is no longer overlapping a trigger area.
    In my example I have a "baddie" tag and there is only 1 in my scene for testing. Soon as it stops overlapping, it calls the "exit" as it should, but then runs the "stay" code block after it has already exited that region.

    It is possible that it is calling them in the right order, but for some reason the code is not being executed in that order. It is as if it is stacking everything up into a pile, then running back through the pile backwards.
     
  5. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,546
    @CoolJosh3k Well, as I mentioned, it is doing as expected for me when I run your code, just one object as a trigger and one object to collide through it that I have the script on, and the execution order is proper. What version of Unity are you on and have you tried updating to a new patch version?
     
    Suddoha likes this.
  6. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Perhaps there's another object with a trigger that causes OnTriggerStay to happen. You should check for that - just put a Debug.Log printing the GO's name that caused OnTriggerStay to happen again. Like @Invertex said, if there's only one trigger object and only the object with your script attached, you should get the correct results, unless you re-enter the same trigger again.

    For debugging purposes, either attach he debugger to the process and set a breakpoint or simply change the scripts to be:

    Code (CSharp):
    1. private void OnTriggerStay(Collider other)
    2. {
    3.     Debug.Log("Stay: " + other.name);
    4. }
    5.  
    6. private void OnTriggerExit(Collider other)
    7. {
    8.     Debug.Log("Exit: " + other.name);
    9. }
    If it outputs the same, you may also add OnTriggerEnter to check how often / when you enter the trigger.
     
    Last edited: Sep 24, 2017
  7. CoolJosh3k

    CoolJosh3k

    Joined:
    Dec 3, 2016
    Posts:
    145
    In a test project, all works as expected.
    Trying to Debug.Log on my main project actually slows everything to a very slow crawl. I am thinking there is something more to this and that I have made a mistake somewhere.

    Was using 2017.1.0p4. Upgrading to 2017.1.1f1 and will report back soon.
     
  8. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,546
    p3 is latest, not f1
    https://unity3d.com/unity/qa/patch-releases
     
  9. CoolJosh3k

    CoolJosh3k

    Joined:
    Dec 3, 2016
    Posts:
    145
    Took me some time, but found the cause. It is always something silly so I am not too surprised.

    Code (CSharp):
    1.  
    2.    
    3.     void OnTriggerExit(Collider other) {
    4.         if (!gameManagerScript.firstPerson) {
    5.             if (other.tag == "HidePlayerZone") {
    6.                 renderer.enabled = true;
    7.             }
    8.         } else if (other.tag == "FlipDiscRespawnZone") {
    9.             gameManagerScript.isPlayerInFlipDiscRespawnZone = false;
    10.         } else if (other.tag == "Hurt") {
    11.             hurting = false;
    12.         }
    13.     }
    Since it was behind an else statement, it did not ever run if it was inside another valid colliders. *Facepalm*.

    Thanks for the support everyone.