Coroutine never stops...

Hi.

I made two Coroutines.

One for wander and one for chase.

I used all kind of code to make wander stops when chasing, but it almost never chases player and wander.

I used yield break, yield return null, stopcoroutine, named it with string, etc…

But it never stops wandering…

I just let them yield break to see if it will make my wandering stops, but it doesn’t!!

Here is my code.

Help me God bless you all.

    public Transform sight;
	public GameObject Player;
	NavMeshAgent navMeshAgent;
	NavMeshPath path;
	public float timeForNewPath;
	Vector3 target;
	bool inCoRoutine;
	bool chasing;
	




	void Start()
	{
		navMeshAgent = GetComponent<NavMeshAgent> ();
		path = new NavMeshPath ();
		chasing = false;
		navMeshAgent.speed = speedController.speedValue;

	}		
		

	void Update()
	{
                // Two CoRoutines with chasing and wandering.
		if (!inCoRoutine && !chasing) 
		{
			StartCoroutine ("Wandering");
			StopCoroutine ("Chase");
		}

		if (chasing) 
		{
			StartCoroutine ("Chase");
			StopCoroutine ("Wandering");
		}

                //This is for move animation.
		if (navMeshAgent.velocity.magnitude > 1.0f) 
		{
			anim.SetBool ("IsWalking", true);
		} 
		else
		{
			anim.SetBool ("IsWalking", false);
		}

	}

	Vector3 getNewRandomPosition()
	{
		float x = Random.Range (-45, -5);
		float y = Random.Range (-0.2f, 0.2f);
		float z = Random.Range (-33, 25);

		Vector3 pos = new Vector3 (x, y, z);
		return pos;
	}

	IEnumerator Wandering()
	{
		if (!chasing) 
		{
			inCoRoutine = true;
			yield return new WaitForSeconds (timeForNewPath);
			GetNewPath ();
			inCoRoutine = false;

		}

		if (chasing) 
		{
			yield break;
		}

	}

	IEnumerator Chase()
	{
		if (chasing) 
		{
			GetNewPath ();
			yield return new WaitForSeconds (timeForNewPath);
			target = Player.transform.position;
			navMeshAgent.SetDestination (target);

		}

		if (!chasing) 
		{
			yield break;
		}

	}

		

	void GetNewPath()
	{
		if (!chasing) 
		{
			target = getNewRandomPosition ();
			navMeshAgent.SetDestination (target);
		} 
		else if (chasing) 
		{
			target = Player.transform.position;
			navMeshAgent.SetDestination (target);
		}
	}
	
			


	void OnTriggerStay()
	{
		Ray ray = new Ray (sight.position, sight.forward);
		RaycastHit hit;
		if (Physics.Raycast (ray, out hit, 30.0f)) 
		{
			sight.LookAt (Player.transform.position);
			if (hit.transform.CompareTag ("Player")) 
			{
				chasing = true;
				Debug.Log ("Hello");
			} 
			else 
			{
				chasing = false;
				Debug.Log ("No");
			}
		}
	}

	void OnTriggerExit()
	{
		chasing = false;
	}

}

I know, the solution I propose is a total reworking of what you currently have, and it goes outside of the scope of your question.

I advise you to get rid of your coroutines which are difficult to handle in the Update function. Instead, manage your delay inside the Update function directly.

An additional improvement is to use the Strategy pattern to handle the states of your player. It will simplify your player class and you easily be able to create new states.

public Transform sight;
public GameObject Player;
public float timeForNewPath;

private NavMeshAgent navMeshAgent;
private NavMeshPath path;
private BehaviourState state; // 
private int walkingHash ;

void Start()
{
    navMeshAgent = GetComponent<NavMeshAgent> ();
    navMeshAgent.speed = speedController.speedValue;
    path = new NavMeshPath ();
    walkingHash = Animator.StringToHash( "IsWalking" ) ; // Use this to optimize the call to SetBool
    
    state = new WanderState( navMeshAgent, timeForNewPath );
}

void Update()
{
    state.Update(); // The NavMeshAgent will automatically retrieve the path at the specified interval
    anim.SetBool( walkingHash, navMeshAgent.velocity.magnitude > 1.0f );
}

void OnTriggerStay()
{
    Ray ray = new Ray (sight.position, sight.forward);
    RaycastHit hit;
    if (Physics.Raycast (ray, out hit, 30.0f)) 
    {
        sight.LookAt (Player.transform.position);

        // If the player is in sight, activate the chase mode => create a new state which is updated in the Update function
        if (hit.transform.CompareTag ("Player")) 
        {
            if( !( state is ChaseState ) )
                state = new ChaseState( navMeshAgent, timeForNewPath, hit.transform );
        } 
        // If not, activate the wander mode => create a new state which is updated in the Update function
        else if( !( state is WanderState ) )
        {
            state = new WanderState( navMeshAgent, timeForNewPath );
        }
    }
}

void OnTriggerExit()
{
    if( !( state is WanderState ) )
    {
        state = new WanderState( navMeshAgent, timeForNewPath );
    }
}

public abstract class BehaviourState
{
    protected NavMeshAgent navMeshAgent ;
    private float targetAcquisitionInterval;
    private float lastTargetAcquisitionTime ;
    
    public BehaviourState( NavMeshAgent agent, float interval )
    {
        navMeshAgent = agent ;
        targetAcquisitionInterval = interval;
    }
    
     public void Update()
     {
         //Debug.Log( Time.time + " " + lastTargetAcquisitionTime );
         if( Time.time > lastTargetAcquisitionTime + targetAcquisitionInterval )
             GoToTarget() ;
     }
 
 private void GoToTarget()
 {
	 navMeshAgent.SetDestination ( GetTargetPosition() );
	 lastTargetAcquisitionTime = Time.time ; 
 }
    protected abstract Vector3 GetTargetPosition(); 
}

public class WanderState : BehaviourState
{    
    public WanderState( NavMeshAgent agent, float interval ) : base ( agent, interval )
    {
         GoToTarget() ;
    }

    protected override Vector3 GetTargetPosition()
    {
        float x = Random.Range (-45, -5);
        float y = Random.Range (-0.2f, 0.2f);
        float z = Random.Range (-33, 25);

        Vector3 pos = new Vector3 (x, y, z);
        return pos;
    }
}

public class ChaseState : BehaviourState
{
    private Transform target ;
    
    public ChaseState( NavMeshAgent agent, float interval, Transform t ) : base( agent, interval )
    {
         target = t ;
         GoToTarget() ;
    }
    
    protected override Vector3 GetTargetPosition()
    {
        return target.position ;
    }
}

I re-exported my model and it worked. Thx for helping me out!