My weapon doesn't subtract ammo for a period of time after reloading.

So basically, I have this weapon script that works fine for the most part, it’s got a mag size, projectile speed, fire rate, and a reload time. It all works fine up until you reload, where it sets loaded to true and refills your ammo supply. Problem is that for a time after reloading, you can shoot the weapon without the ammo counter going down at all. A second or two after reloading, it subtracts ammo as normal. With this particular gun I should be able to fire two shots, take a 2 second reload, and fire two shots again, but I can fire 4 shots, with the first 2 not making to ammo counter go down, any help?

using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;

public class DoubleBarrel : MonoBehaviour
{
    public GameObject model;
    public GameObject bulletPrefab;
    public Transform firePoint;

    private bool canFire = true;
    private bool loaded = true;

    public float range = 2f;
    public float fireSpeed = 0.5f;
    public float projectileSpeed = 30f;
    public float reloadSpeed = 2f;
    public float mag = 2f;
    public float ammo;

    private void Start()
    {
        ammo = mag;
    }
    
    private void Update()
    {
        if(ammo <= 0)
        {
            loaded = false;
            Reload();
        }
    
        if(loaded == true)
        {
            if (canFire == true)
            {
                if(Input.GetMouseButton(0))
                {    
                    canFire = false;
                    Fire();
                    ammo--;
                    Wait();
                }
            }
        }
    }

    public async void Reload()
    {
        await Task.Delay((int)(reloadSpeed * 1000));
        loaded = true;
        ammo = mag;
    }

    public async void Wait()
    {   
        await Task.Delay((int)(fireSpeed * 1000));
        canFire = true;
    }
    
    void Fire()
    {

        var offset = Random.Range(-20, 20);

        model.transform.eulerAngles = new Vector3(
        model.transform.eulerAngles.x,
        model.transform.eulerAngles.y,
        model.transform.eulerAngles.z + offset);

        GameObject bullet = Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
        bullet.GetComponent<Rigidbody2D>().AddForce(firePoint.up * projectileSpeed, ForceMode2D.Impulse);    
        
        model.transform.eulerAngles = new Vector3(
        model.transform.eulerAngles.x,
        model.transform.eulerAngles.y,
        model.transform.eulerAngles.z - offset);
    }
}

Sometimes it’s easier to start again than try and fix some code and I think this is one of those occasions. For example, you have both “loaded” and “canFire” but you only need “canFire” (I believe). Couple more things. I prefer Coroutines because of a documented worry with async await. Do you want GetMouseButtonDown for firing? That way you have to click twice, which seems more natural.

Anyway, have a look at my simplified code and I think it will suit you well enough. I think it’s more elegant than your solution and so easier to understand. Let me know what you think…

using System.Collections;
using UnityEngine;

public class Shoot : MonoBehaviour
{
    [SerializeField] float reloadTime = 0.5f;
    [SerializeField] float refireTime = 2;

    int mag = 2;
    int ammo;

    bool canFire;

    void Start()
    {
        Reload();
    }

    void Update()
    {
        if (canFire && Input.GetMouseButtonDown(0))
            Fire();
    }

    void Fire()
    {
        Debug.Log("Firing");
        ammo--;
        if (ammo == 0)
            StartCoroutine(WaitForReload(reloadTime));
        else
            StartCoroutine(WaitForFire(refireTime));
    }

    void Reload()
    {
        ammo = mag;
        canFire = true;
    }

    IEnumerator WaitForFire(float waitTime)
    {
        canFire = false;
        yield return new WaitForSeconds(waitTime);
        canFire = true;
    }

    IEnumerator WaitForReload(float waitTime)
    {
        canFire = false;
        yield return new WaitForSeconds(waitTime);
        Reload();
    }
}