Shooting one bullet at a time

How do I change the following script so when I hold down the shooting button, it shoots out a bullet every 0 to 5 seconds?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ShootBullet : MonoBehaviour
{
    public Transform spawnPoint;
    public GameObject Bullet;
    public float speed = 15f;
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetButton("Fire1"))
        { 
            shootBullet(); 
        }
    }

    private void shootBullet()
    {Quaternion originalRotation = transform.rotation;

    // Face the camera temporarily
    transform.rotation = Camera.main.transform.rotation;

    // Instantiate and shoot the bullet
    GameObject cB = Instantiate(Bullet, spawnPoint.position, Bullet.transform.rotation);
    Rigidbody rb = cB.GetComponent<Rigidbody>();
    rb.AddForce(transform.forward * speed, ForceMode.Impulse);

    // Restore original rotation
    transform.rotation = originalRotation;

    }
}

You can have a float variable to which you add Time.deltatime each frame, once it is greater than 5 use your shootBullet() method and reset it to 0.

float passingTime = 0;
void Update()
    {
        if (Input.GetButton("Fire1"))
        { 
            passingTime += Time.deltaTime
            if( passingTime > 5) 
            {
                shootBullet(); 
                passingTime = 0;
            }
        }
    }

If you want a first shoot before the intervals, have your value start already at 5 and reset to 5 when the key is released (in your else). But this will create the possibility to shoot faster by spamming the button instead of waiting for the autoshoot.

if you don’t want this behavior, you can add the time outside of your input check,
and just reset it to 0 when you press and its greater than 5.

float passingTime = 5;
void Update()
    {   
        passingTime += Time.deltaTime
        if (Input.GetButton("Fire1"))
        {     
            if( passingTime > 5) 
            {
                shootBullet(); 
                passingTime = 0;
            }
        }
    }

You can also use coroutines but it will introduce complexity, especially if you’re not familiar with them.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ShootBullet : MonoBehaviour
{
    public Transform spawnPoint;
    public GameObject Bullet;
    public float speed = 15f;
    private bool isShooting = false;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            isShooting = true;
            StartCoroutine(ShootRepeatedly());
        }
        if (Input.GetButtonUp("Fire1"))
        {
            isShooting = false;
            StopCoroutine(ShootRepeatedly());
        }
    }

    IEnumerator ShootRepeatedly()
    {
        while (isShooting)
        {
            shootBullet();
            yield return new WaitForSeconds(Random.Range(0f, 5f));
        }
    }

    private void shootBullet()
    {
        Quaternion originalRotation = transform.rotation;

        // Face the camera temporarily
        transform.rotation = Camera.main.transform.rotation;

        // Instantiate and shoot the bullet
        GameObject cB = Instantiate(Bullet, spawnPoint.position, Bullet.transform.rotation);
        Rigidbody rb = cB.GetComponent<Rigidbody>();
        rb.AddForce(transform.forward * speed, ForceMode.Impulse);

        // Restore original rotation
        transform.rotation = originalRotation;
    }
}

In this modified script:

  • I added a boolean variable isShooting to keep track of whether the shooting button is held down.
  • I modified the Update method to start and stop shooting when the shooting button is pressed and released, respectively.
  • I introduced a coroutine ShootRepeatedly which continuously calls shootBullet with a random delay between 0 and 5 seconds as long as isShooting is true.
  • When the shooting button is released (GetButtonUp("Fire1")), the coroutine is stopped using StopCoroutine.