How to get a for loop to run once per coroutine?

I am trying to make an AI (my first one without tutorials) and I am having a bug that completely ruins the AI. I have an array of points that I want to cycle through but instead of it adding one then going to the next point it goes straight from 0 for a while to 1,2,3 really fast, confusing the AI. It seems like it is running the complete for loop every time it passes through when I only want the for loop to do it once per coroutine Here is the script:

// Start is called before the first frame update
void Start()
{
    noise = transform.GetChild(0).gameObject;
    noiseAnim = GetComponent<Animator>();
    chosenNo = 0;
    chosen = patrol[chosenNo];
}

// Update is called once per frame
void Update()
{
    StartCoroutine(Move());
    Debug.Log(chosenNo.ToString());
}
IEnumerator Move()
{
    if (noise.GetComponent<Soundwave>().sense == true)
    {
        lastKnownPoint = noise.GetComponent<Soundwave>().point;
        transform.position = Vector2.MoveTowards(transform.position, lastKnownPoint.position, speed * Time.deltaTime);
        yield return null;
    } else if (noise.GetComponent<Soundwave>().sense == false)
    {
        if (transform.position == chosen.position)
        {
            for (; chosenNo < patrol.Length; chosenNo++)
            {
                noiseAnim.SetTrigger("Screech");
                yield return new WaitForSeconds(waitTime);
                chosen = patrol[chosenNo];
            }
            if (chosenNo >= patrol.Length || chosen == null)
            {
                chosenNo = 0;
            }
        }
       if (transform.position != chosen.position)
       {
           transform.position = Vector2.MoveTowards(transform.position, chosen.position, speed * Time.deltaTime);
       } 
    }
}
private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.tag == "Player")
    {
        noise.GetComponent<Soundwave>().sense = true;
        noise.GetComponent<Soundwave>().player = collision.gameObject;
    }
}
private void OnTriggerExit2D(Collider2D collision)
{
    StartCoroutine(Move());
}

Any help would be great thanks :slight_smile:

It looks like the only way your issue could happen is if you change the value of waitTime, however corourtine execution is dependent on the frame rate - if your fps is varying due to the cpu load your game is pulling, WaitForSeconds will be innacurate.

What is your waitTime, and can you verify it is not changing?

Here is an alternate, sample coroutine loop in pseudoCode that might solve your problem:

waitTime = 1000f;  // wait for one second in milliseconds
// do the loop
int itemIndex = 0;
float currentTime = 0;
while( itemIndex < itemList.Count ){
    if( currentTime >= waitTime ) {
           process itemList[ itemIndex ];
           currentTime = 0;
           itemIndex++;
    }
    yield return null; // or perhaps new WaitForFixedUpdate();
    currentTime += Time.deltaTime;
}

I think this will allow you a finer grained response time that WaitForSeconds will if the problem is due to the frame rate dropping or speeding up. To that end, you might want to use WaitForFixedUpdate. While you are guaranteed a certain number of FixedUpdate frames, like all timing issues in Unity, the time between them is not.