About 'Repeat Fire Coroutine'!

In this video (objectives)…

  1. Create a coroutine to call when firing.
  2. Loop the coroutine using a while (true) loop.
  3. Create a means in which to stop the coroutine.

After watching (learning outcomes)… Use coroutine to create repeating fire when the player is holding down the shoot button.

(Unique Video Reference: 9_LD_CUD)

We would love to know…

  • What you found good about this lecture?
  • What we could do better?

Remember that you can reply to this topic, or create a new topic. The easiest way to create a new topic is to follow the link in Resources. That way the topic will…

  • Be in the correct forum (for the course).
  • Be in the right sub-forum (for the section)
  • Have the correct lecture tag.

Enjoy your stay in our thriving community!

Sorry, but I can’t find the video of this lecture in udemy. It jumps to the next…

1 Like

There seems to be a problem with this video. When trying to access it, it immediately jumps to the next video called GameObject Shredder.

1 Like

for no reason udemy says its there but it has a 0:00 time… is something wrong with the video?

If you choose the “Lecture Project Changes”, you can see what has been changed to make the Coroutine work. Try that and then come back to the video when they have fixed it.

If there is a video issue it would be best to post that on the Udemy platform under the Q&A for the specific lecture. The instructors do not always frequent the forum and the course has student instructors, who, if unable to resolve the problem can escalate it for the instructor’s attention. :slight_smile:

Of course, you can also tag @Rick_Davidson for example and see if that gets results too :slight_smile:

1 Like

Thanks for pointing this out guys. It looks like the video upload failed. I’m re-uploading now.

3 Likes

Something that I found while working on this challenge (another mini-challenge even though the video wasn’t showing up) was that multiple turbo-firing coroutines can be launched at once. In effect, this allows the player to double, triple, or even quadriple or more the rate of fire.

I am not sure if this was intended, but I did a bit of troubleshooting and found a way to use a boolean to restrict the player to the preferred rate of fire:

private bool notYetFiring = true;

    private void Fire()
    {

        if (Input.GetButtonDown("Fire1") && notYetFiring)
        {
            notYetFiring = false;
            firingCoroutine = StartCoroutine(FireContinuously());
        }
        if (Input.GetButtonUp("Fire1"))
        {
            StopCoroutine(FireContinuously());
        } 
    }

    IEnumerator FireContinuously()
    {
        while(Input.GetButton("Fire1"))
        {
            GameObject laser = Instantiate(laserPrefab, transform.position, Quaternion.identity) as GameObject;
            laser.GetComponent<Rigidbody2D>().velocity = new Vector2(0, projectileSpeed);
            yield return new WaitForSeconds(firingInterval);
        }
        notYetFiring = true;
} 

Hopefully this will be helpful for anyone else trying to restrict the rate of fire. :wink:

1 Like

Looks like a good solution. I haven’t found the issue you’re talking about but I’m guessing that if the player is spamming the shoot button that it can accidentally trigger multiple firing coroutines concurrently.

Yup, that was the issue. Thanks again for all the work you put into this course, I am enjoying it immensely and learning a lot along the way.

I’m seeing the coroutines as something that you call to run, and it execute the pile of instructions in paralel to the main code. This is an correct way to think about it?

What if, instead of a coroutine, I use the GetButton and limite the firing with some counter, just like the enemy method? What is the pros and cons related to the coroutine?

Thanks!

1 Like

The problem only presents itself when there are multiple buttons are used to fire lasers. For example I can shoot with the mouse and then shoot with the space bar as well. Somehow this throws it into a loop and not only does it stack up the coroutines but for some reason it won’t stop the one of the coroutines. I think it has something to do with only stopping the coroutine that was declared as a variable and not the other one created.

1 Like

you can delete:
if (Input.GetButtonUp(“Fire1”))
{
StopCoroutine(FireContinuously());
}
and it will still work as intended, why stop a coroutine with no infinite loop? it’s just gonna end when you stop pressing “Fire1” (that’s the condition in your while loop).
Am I wrong?

You are not wrong.

The StopCoroutine() function is unnecessary and redundant in this current set of code and was a vestigial remainder from before I implemented the while loop. Thanks for pointing that out!

Hey Rick,
Why dont we use Input.GetButton(“Fire1”) instead of using GetButtonDown? That way our ship fires as long as we hold the button down and we dont have to use both while(true) sentence and the if GetButtonUp sentence to stop.

Hi Ahmet, we use this approach because of the coroutine - we want to have bullets starting and stopping very quickly while the button is down, but if we use GetButtonDown then it will fire over a gazillion coroutines and cause a mess. This way we are using a trigger of button down starting the process and button up stopping the process.

Thanks for your answer Rick, I dont know if my question was clear but I wanted to mean this sentence: GetButton
I noticed that unlike GetButtonDown this function stops by itself when you release the button.

Guys I just feel your solution to the problem a bit weird. I got some little experience in Unity. But the way I did the firing was:

Here I’m using a Timer to make a rate of firing. That from my perspective feels better than a Coroutine, cause they are more expensive.

        shootingCadence -= Time.deltaTime;
        if (shootingCadence <= 0 && Input.GetMouseButton(0))
        {
            LaserBullet bullet = Instantiate(currentWeapon, shootingSocket.transform.position, Quaternion.identity);
            SetShootingCadence();
        }

By the way the impulse for the bullet is handle by the Bullet.cs

And for destroying the lasers instead of making a collider and stuff at the end of the screen. I made a Bullet.cs that is attached to the laser.

And there I got this:

    void OnBecameInvisible()
    {
        Destroy(gameObject);
    }

I just feel the desire to share this.

About the double control execute the Coroutine, I did like that

   if (Input.GetButtonDown("Fire1"))
        {
            if (firingCoroutine != null)
            {
                StopCoroutine(firingCoroutine);
            }
            firingCoroutine = StartCoroutine(FireContinuously());
        }

this way I can left all controls freely assigned, in case of double press of one fire control the fire will stop untill another fire button is pressed. This prevent the superturboshooting spawn too.

I have made games similar to this in the past with different languages. We would typically just add a manual timer back then so that the shots would wait however much time before being allowed to fire again. I’m guessing the advantage to using a coroutine instead of just adding a timer and checking vs Time.time is standardization? I’m not actually sure if against this lesson is even the best place for the question. Coming from older C style languages there’s a lot of interesting new features with Unity and C# that make life easier. Also a lot of old habits to unlearn.

Privacy & Terms