[C#] Coroutine Runs Multiple Times

I’m trying to make my AI and recently I posted a thread regarding my repeating Invoke being called multiple times, it was because I was Invoking in the update. I had to return to coroutines, now that I understand those, I’ve run into the exact same issue. I’ve been looking everywhere, but to no avail.

  • Here’s my code
using UnityEngine;
using System.Collections;

public class AIPlayerControllerV2_1 : MonoBehaviour {

    //Version 2.1 of AIPlayerController
    //Created by SwaggyMcChicken on 9/29/2015
    //Additions: Allows AI to block, attack, ... (still in development of 2.1)
   
    public AICharacterAnimatorv2 AICharAnim;
    public AIPlayerCombat AIPlayComb;
    public CharacterAnimator CharAnim;
    public CharacterController CharCont;
   
    public Transform Player;
    Vector3 Target;
    Quaternion NewRotation;
   
    public Vector3 MoveDirection;
    public float Speed;
    public float Distance;
   

    public bool PromptAttack;
    public bool PromptBlock;
    public bool PromptStun;
    bool Travelling;
    bool CanTakeAction;
    int Chance;
    int ChanceMax;
    int ChanceMin;
    int MoveZ;
    int MoveX;
    int MoveY;
   
    void Start () {
       
        Travelling = false;
        ChanceMin = -6;
        ChanceMax = 3;
   
    }
   
    void Update () {
       
        Target = Player.position - transform.position;
        NewRotation = Quaternion.LookRotation (Target);
        NewRotation.eulerAngles = new Vector3 (0, NewRotation.eulerAngles.y, 0);
        transform.rotation = NewRotation;
       
        PromptAttack = false;
        PromptBlock = false;
        PromptStun = false;
        CanTakeAction = false;

        Distance = Vector3.Distance(transform.position,Player.position);
        Chance = Random.Range(ChanceMin,ChanceMax);
       
        if (Distance > 3){
           
            Travelling = true;
           
        }
       
        else if (Distance < 2){
           
            Travelling = true;
           
        }
       
        else if(Distance < 3 && Distance > 2){
           
            Travelling = false;
           
        }
       
        else {

            Travelling = false;
            CanTakeAction = true;
           
        }



        StartCoroutine(FindRun((i)=>{MoveZ = i;}));



        if (CanTakeAction == true){

            if(CharAnim.Attacking == true){

                PromptBlock = true;

            }

            else if(CharAnim.Stunned == true){

                PromptAttack = true;

            }

        }   
       
        MoveDirection = new Vector3 (MoveX, MoveY, MoveZ);
        MoveDirection = transform.TransformDirection(MoveDirection);
        MoveDirection *= Speed;
       
    } // Closes Update
   
    void FixedUpdate(){
       
        CharCont.Move(MoveDirection * Time.deltaTime);
   
    } // Closes FixedUpdate
   
   
   
   
    //NOTE Below are custom made functions for decision making
   
    IEnumerator FindRun(System.Action<int> callback){

        yield return new WaitForSeconds(1f);

        if (Distance > 3){
           
            callback(1);
           
        }
       
        else if (Distance < 2){
           
            callback(-1);
           
        }
       
        else{

            MoveZ = 0;
            Travelling = false;
       
        }

        Debug.Log(MoveZ);
       
    } // Closes FindRun

} // Closes Class

You’re starting a coroutine in the Update loop. Which means, every time Update is called (i.e. every frame) you’re starting another FindRun coroutine.

I would suggest putting the StartCoroutine at the end of your coroutine. This will cause the coroutine to repeat itself automatically, unless you use StopCoroutine to stop it.

Better yet, wrap it up in a while loop.