OnTriggerExit not working as expected

Hello, people!
I am experiencing a frustrating issue that I have not encountered before. I am using triggers in a project of mine. I have already looked up many answers.unity3d.com topics, but none of them is what I need. I have set up my triggers properly- IsTrigger is checked on whatever needs to be a trigger and also rigidbodies are added.

Enemy:

has a sphere collider ticked as a trigger

has a rigidbody

has a script Enemy.cs which contains the OnTriggerxxx() functions

has a navmesh agent to move around (wander to randomly chosen objects with colliders from an array while in wanderState)

Player:

Has a rigidbody

has its collider

has its script to move him around

has a tag “Player”

So far so good, trigger detection IS working. I am afraid my problem comes from an inability to structure my code logically.

    void OnTriggerEnter(Collider col)
    {                  
            if (currentState == wanderState)
            {
                if (col.gameObject.tag == "Player" && m_target.gameObject.tag != "Player")
                {
                    print(col.gameObject.tag);
                    wanderState.Detected(col.gameObject);  //sets the target to the player
                }

                if (col.gameObject.tag == "WanderPoint")
                {
                    print(col.gameObject.tag);
                    wanderState.changeWanderPoint();
                    col.gameObject.SetActive(false);
                }
            }
    }

    void OnTriggerExit(Collider col)
    {
        if (currentState == wanderState)
        {
            if (col.gameObject.tag == "Player")  /* if I comment out this if-statement, this problem disappears, but the enemy follows me around the whole world without changing its target (ye, obviously m8, no code to change its target) which is obviously how I don't want the game to be. */
            {
                wanderState.changeWanderPoint();  /* this is where the problem occurs. The Player, even while staying inside the enemy's sphere collider, is treated as if he is exiting it, hence this function gets called repeatedly */
            }

            if (col.gameObject.tag == "WanderPoint")
            {
                col.gameObject.SetActive(true);
            }
        }
    }
`

Brief explanation: I am using a State Design Pattern implementation to control the behavior of the enemy. 
currentState is a State variable (State being an interface), which holds concrete states that inherit from the interface(nothing to do with the problem, just FYI). Inside Enemy.cs there is a gameObject variable m_target which contains the target for the navmesh agent.

While the Player is inside the Enemy's sphere collider, the enemy just gets stuck in one place, because he doesn't get a single target to go to, instead it is being changed every frame. And while the player is within the enemy trigger the target should be the player. 

My confusion probably comes from the fact that I am not fully aware of how the OnTrigger functions are called, although what I know about them is that OnTriggerEnter() and Exit() should only be called when their respective actions occur (if a collider enter the trigger, if-statement whether it is a particular tag, same with the Exit()). OnTriggerStay() is supposed to be called every frame to check whether something continues to be within the borders of the collider. Am I wrong with this information? It makes no sense for the Player to be treated as if exiting the trigger while within it.

Thank you very much in advance to anyone who will take the time to help! It will be greatly appreciated.
`

As you point out, it’s a problem in your logic rather than in OnTriggerExit itself. But it’s hard for anyone else to point out your mistakes when we only have partial code. A few comments that spring to mind:

  • You test whether currentState == wanderState in both functions, but never seem to set currentState to any other values. What other values can it take, and what changes it?
  • What does changeWanderPoint() or Detected() do?
  • Lines 29-32 you test whether a “WanderPoint”-tagged object leaves the trigger. But that can’t ever be true since, in lines 11-16, if a “WanderPoint” enters the trigger, you set it to be inactive.
  • When the player exits the trigger, I’m guessing you meant to set m_target.gameObject to null? (Or perhaps, to an aribtrary wander point?)

Your knowledge on how the OnTrigger functions work is correct. I am a bit curious about the wanderState.changeWanderPoint(); function code because for right now I don’t see too much wrong in the OnTrigger functions so maybe you have a bad loop somewhere. What it sounds like is that you may have a small part of the player that is also tagged as “Player” (like hair, weapon, etc) that may be entering and leaving the collision bounds when the enemy moves causing a repeated function call. Another thing is that you may be inadvertently calling this function elsewhere in the code (like in the Update() function or another condition check) so you could try dropping a debug.log() with the name of the function calling the changeWanderPoint(); method.

Debug.Log("Collided with "+col.gameObject.name);
Debug.Log("Changing Wander Point from OnCollisionEnter()");

Debug.Log("Exiting collision with "+col.gameObject.name);
Debug.Log("Changing Wander Point from OnCollisionExit()");

Last thing I could suggest is changing the currentState so it isn’t the same as wanderState in the OnCollisionExit() to see if it really is messing with it.

@JincSoft & @tanoshimi
So I just managed to find a solution to my problem. I checked my Enemy’s ‘IsKinematic’ on his rigidbody. Absolutely no other change in the code or the prefabs. So I would guess that some optimization in Unity is causing the OnTriggerEnter and OnTriggerExit to fire simultaneously and repeatedly every frame in my specific situation. Player was not changed, but Enemy is now kinematic. This has now made the transition between targets work as supposed to

Since this is a top result on Google I wanted to link to a more robust solution
https://forum.unity.com/threads/fix-ontriggerexit-will-now-be-called-for-disabled-gameobjects-colliders.657205/

Similar issue with me andthe only fix that works is isKinematic flag on the enemy rigidbody.Navmaesh agents work wierd when its disabled triggers work wierd when its disabled and the object in concern has a navmesh agent even if its disabled.No other fix works.