Bug: Spamming fire allows for faster shooting

It seems that spamming the fire button allows for faster firing.
My guess is that fire() is called every frame, and when isFireing == false it stops the corutine (if there is any) and sets fireingCorutine to null.
since fire fireingCorutine == null, you could then press the fire button anew to start the coroutine again, creating another projectile.

1 Like

I just made a fix to this.
create a new bool hasFired = false;

in your Fire methods first if statment add: && hasFired == false . it should look like this:
if(isFireing && fireingCoroutine == null && hasFired == false)

in FireContinuesly add
hasFired = true;
StartCoroutine(FireController());
Before the “yield return new WaitForSeconds(fireingRate);”
(i put those two lines just above it, after the “Destroy(instance, projectileLifetime);”)

make a new method like this
IEnumerator FireController()
{
yield return new WaitForSeconds(fireingRate);
hasFired = false;
}

all this will make sure that the FireContinuously() coroutine can’t be started before your fire rate delay has happened.

3 Likes

I solved this by getting rid of the StopCoroutine() completely, and letting the Coroutine end by itself when isFiring is false.

Fire() now looks like this:

    void Fire(){
        if(isFiring && firingCoroutine == null){
           firingCoroutine = StartCoroutine(FireContinuously());
        }
    }

The coroutine like this:

    IEnumerator FireContinuously(){
        while(isFiring){
            GameObject currentProjectile = Instantiate(projectilePrefab, transform.position, Quaternion.identity);
            Rigidbody2D rb = currentProjectile.GetComponent<Rigidbody2D>();
            if(rb != null){
                rb.velocity = new Vector2(0, projectileSpeed);
            }
            
            Destroy(currentProjectile, projectileLifeTime);
            yield return new WaitForSecondsRealtime(firingCoolDown);
        }
        firingCoroutine = null;
    }

So when the player stops firing, the coroutine still waits for our firing rate, then ends itself and sets the reference to null - which allows us to start a new coroutine if the player starts shooting. This way, when the player stops shooting the coroutine isn’t immediately deleted, but still has to wait for the firing delay.

2 Likes

This is not a bug, the code was written for the player to have a 0 fire rate. Unfortunately, changing the player’s baseFiringRate will result in a random fire rate - which was intended for the AI. You can control this by changing the code in the coroutine that chooses the time to the next projectile

In the coroutine, add a check for useAI and only pick a random value if it is the AI

            float timeToNextProjectile = baseFiringRate;
            if (useAI)
            {
                timeToNextProjectile = Random.Range(baseFiringRate - firingRateVariance,
                                            baseFiringRate + firingRateVariance);
            }

Now you can control the player’s firing rate as well as the AI’s firing rate

Privacy & Terms