Home > Back-end >  Setting a fire rate for a weapon in Unity
Setting a fire rate for a weapon in Unity

Time:07-14

I am trying to set a fire rate in Unity so that when I hold down up arrow, I will shoot a projectile up every 1 second. Currently my code is shooting a projectile every frame update, even though I have a Coroutine set up.

public GameObject bulletPrefab;
public float bulletSpeed;
public float fireRate = 1f;
public bool allowFire = true;   
void Update()
    {
        //shooting input
        if (Input.GetKey(KeyCode.UpArrow) && allowFire == true)
        {
            StartCoroutine(Shoot("up"));

        }
        
    }

    IEnumerator Shoot(string direction)
    {
        allowFire = false;
        if (direction == "up")
        {
            var bulletInstance = Instantiate(bulletPrefab, new Vector3(transform.position.x, transform.position.y, transform.position.z   1), Quaternion.identity);
            bulletInstance.GetComponent<Rigidbody>().AddForce(Vector3.forward * bulletSpeed);
        }
        yield return new WaitForSeconds(fireRate);
        allowFire = true;

    }

CodePudding user response:

Coroutine

You can use the coroutine, but since you're calling it in an Update loop you much wait for it to finish before starting another one.

Coroutine currentCoroutine;
    
if(currentCoroutine == null)
    currentCoroutine = StartCoroutine(DoShoot());

IEnumerator DoShoot() {
    // Shoot.
    yield return new WaitForSeconds(1f);
    currentCoroutine = null;
}

Timestamp

You can also use a timestamp for when cooldown is ready. It's basically current time plus some duration.

float cooldown = 1f;
float cooldownTimestamp;

bool TryShoot (Vector2 direction) {
    if (Time.time < cooldownTimestamp) return false;
    cooldownTimestamp = Time.time   cooldown;
    // Shoot!
}

CodePudding user response:

I usually end up doing something like:

Variables

[Serializefield] float shootDelay = 1f;  
float T_ShootDelay

Start()

T_ShootDelay = shootDelay;  

Update()

if(T_ShootDelay < shootDelay)
T_ShootDelay  = Time.deltaTime;

ShootInput()

if(T_ShootDelay >= shootDelay)
{
    T_ShootDelay = 0;
    Shoot();
}  

What this does is:

  • Check if the shootDelay timer is less than the shootDelay.
  • Add up the timer by 1 per second.
  • Check the timer's status every time you want to shoot.
  • Set the timer to 0 after shooting

CodePudding user response:

Considering a M4 AR that fires at least 700 rounds per minute.

700 rounds / 60 (seconds) ~= 11,66 rounds per second

1 second / 11 rounds ~= 0,085 seconds of delay between each round

You could simply try this:

yield return new WaitForSeconds(1 / (fireRate / 60f));
  • Related