0
\$\begingroup\$

I need to be able to control the speed in which the gun fires. I'm trying to use the couroutine to limit the speed of update method but it doesn't work for some reason.

I've tried several fireRate values(10K etc.), none of them seem to slow the updates. How can I accomplish this feat?

 float fireRate = 10.1f;

        public IEnumerator CheckFireRate()
        {
            yield return new WaitForSeconds(fireRate);
        }

        void Update()
        {        
            StartCoroutine(CheckFireRate());
            //Fire gun
        }
\$\endgroup\$
1
  • \$\begingroup\$ FIreGun() should be after yield return in CheckFireRate function \$\endgroup\$
    – Nick
    Commented Mar 8, 2020 at 10:23

1 Answer 1

1
\$\begingroup\$
  • Update is called every frame

  • StartCoroutine starts a new coroutine and immediately returns control flow back to the method that called it.

    It does not wait until the coroutine has run to completion (that would cause the game to freeze)

Taken together, what your code currently does:

  • every frame, it starts a new copy of the coroutine waiting for firerate.

    This means you may have dozens of coroutines all waiting in the background.

  • then, every frame, it fires the gun, without waiting for anything the coroutines do.

What you want is something more like this:

// This is a delay period, not a rate.
// The rate of fire is 1 shot divided by this many seconds.
public float firingPeriod = 10f;

// We start our coroutine only once, when the script starts,
// not spawning a new copy of the coroutine in every frame update.
void Start() {
     StartCoroutine(FireLoop());
}

IEnumerator FireLoop() {
    // Loop this coroutine as long as the script stays active/enabled:
    while(true) {
        // Let the game run for some time.
        yield return new WaitForSeconds(firingPeriod);

         // After waiting, fire.
         FireGun();

         // Repeat.
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ Putting the coroutine in Start did the trick. $%^& documentation always puts it in Update. It doesn't even specify that the coroutine is called each time. I thought it was like a static function or something, a one instance thing but apparently not. Thanks once again DMG. \$\endgroup\$ Commented Mar 8, 2020 at 12:10
  • 1
    \$\begingroup\$ The examples in the documentation page for StartCoroutine put it in Start, not Update. If you've ever seen an example with StartCoroutine in Update, it's probably inside an if to ensure it only triggers under a specific circumstance, not every frame. \$\endgroup\$
    – DMGregory
    Commented Mar 8, 2020 at 12:19
  • \$\begingroup\$ You're right. It's in StartCoroutine page specifically. \$\endgroup\$ Commented Mar 8, 2020 at 15:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .