Cleaner solution for continuous fire Coroutine

Rick,

Your method for stopping the coroutine is more complicated than it has to be. I implemented a different method when you challenged us and it does not have the firing bug, plus the code is much simpler. No need to save a handle to the coroutine and it stops itself automatically by simply exiting the method when no button is being pressed.

You can press either or both spacebar and mouse button 0, release either one while keeping the other pressed, and it keeps firing until both are no longer pressed.

[SerializeField]
float   projectileFiringPeriod = 0.25f;

/***
*       Fire() will handle firing the laser from the Player ship.
***/
private void Fire()
{
    if (Input.GetButtonDown("Fire1"))
	{
        StartCoroutine(FireContinuously());
	}   // if
}   // Fire()

/***
*       FireContinuously() will fire the laser from the Player ship and keep
*   firing as long as the space bar or mouse button 0 are pressed.  Presumably
*   it will also work with a joystick, but I don't have one to test with.
***/
private IEnumerator FireContinuously()
{
    do
    {   // Fire laser and check to see if we should keep firing
        // Things to do before
        Vector2 laserStart = new Vector2(transform.position.x,
            transform.position.y + YPadding);   // Start above ship
        GameObject laser = Instantiate(laserPrefab,
            laserStart,
            Quaternion.identity) as GameObject;
        laser.GetComponent<Rigidbody2D>().velocity = new Vector2(0, projectileSpeed);
        Debug.Log("Laser fired, boss");
        yield return new WaitForSeconds(projectileFiringPeriod);
        // Things to do afterwards
        Debug.Log("Checking to see if we should keep firing, boss");
    } while (Input.GetButton("Fire1"));
    Debug.Log("Firing has ceased, boss");
}   //    FireContinuously()
6 Likes

Thank you very much for this solution. It has solved a lot of problems with original code.

2 Likes

I am glad it helped you. I wrote this when he challenged us to write our own and it solved the issue he mentioned later with the mouse and keyboard being pressed at the same time, plus I think the logic is cleaner and easier to understand.

Hi
This way seems to be buggy at an other way. Like this, if you klick 10times during 1 sec, and then hold down the Mousekey, your ShootingSequence will stay in rapidFireMode and still shooting 10times a sec because the Button was not realeased longer than the “FiringPeriod” and pressed again while the loop checked it’s state.

I never had that happen with my code. Could it be due to the value you use in WaitForSeconds(), where it passes projectileFiringPeriod? I have mine set to 0.25f.

Hey TheOnlySmeck,

I fixed that bug by doing the following:

Declare a variable at the top of your Player script
bool isFiring = false;

Now go to your Fire() function, and change the condition for starting the corroutine to:

if(Input.GetButtonDown(“Fire1”) && !isFiring)
{
firingCoroutine = StartCoroutine(FireContinuously());
}

The && means AND, and the ! means NOT, so it will only start the coroutine if the button is down and the isFiring variable is false.

Now, at the end of your Ienumerator coroutine, outside of the while loop, add
isFiring = false;

This way, when the coroutine ends, it lets us know that the player is no longer firing.

3 Likes

Or you could use isFiring = true, and not need to set !isFiring in the conditional. Then you can set the isFiring = false. This is logically more sound, since you’d want isFiring to be a true for all firing instances, but after firing, it is not true.

Yes, I did that myself and I came to the forum to ask if there would be an issue with that solution!

It seems much cleaner than having a while(true) and manually stop the coroutine from outside - although it was nice to learn about stopping coroutines.

1 Like

This is a great solution, but remember that this is a course for beginners and it was created with that purpose in mind, teaching about coroutines without telling how to stop them would be a huge miss.

Since we are talking about iteration statements, here’s a list of them, I think the course covers all except “do” and “await foreach”:

This still has a bug that if you hold both space and mouse 0 down you double your firing speed.

You say that like firing twice as fast is a Bad Thing… :slight_smile:

1 Like

Also has a bug that makes it go completely auto if you touch any other keyboard button before using its intended button. This is evident in the editor mode.

Privacy & Terms