Coroutine Waits, But Calls Multiple Times per Update. Is There a Way to Fix This?

In developing a shooting AI for a third-person shooter project, it made sense to me to try using coroutines and WaitForSeconds in order to create a fire rate for my AI. I believe I have WaitForSeconds set up properly,

IEnumerator doShoot() { yield return new WaitForSeconds(2f); Debug.Log("Shooting"); RaycastHit hit; if (Physics.Raycast(transform.position, (transform.forward + new Vector3(Random.Range(-.1f, .1f), Random.Range(-.1f, .1f), Random.Range(-.1f, .1f))), out hit, shootRange)) { Debug.Log(hit.transform.name); hit.transform.GetComponent<TPSController>().health -= damage; } }

however when I call the coroutine in my Update void, it calls multiple times after waiting 2 seconds is up. For reference, I’ll attach my whole AI script file here. If there’s anything else I can do to improve the script, let me know, but at the moment, my main focus is the delay between shots the enemy AI can take. Everything else works, and that’s good enough right now for me.

Thanks for your help, everyone.

When you call a Coroutine, it establishes a new thread to run the code on. When you use StartCoroutine(…); you are creating a coroutine for every call made. So if you have this code in the update loop then you are calling and creating multiple coroutines (which can be bad for performance).

What you could do instead is either have a boolean to see if the coroutine is currently running or have the coroutine call itself recursively. Either could work, boolean is probably safer.

// For example
bool canShoot = false;
Update: if(canShoot) Shoot();
~End of Shoot, StartCoroutine(Wait())
IEnumerator Wait() { yield return new WaitForSeconds(x); canShoot = true; }