How to make my gun rapid fire and have a 30 bullet clip

I need help with my code
All the tutorials i’ve found on it are outdated and wont work

using UnityEngine;
using System.Collections;

public class m4Gun : MonoBehaviour
{

    public float damage = 20f;
    public float range = 100f;
    public float impactforce = 30f;

    public int maxAmmo = 20;
    public int currentAmmo;
    public float reloadTime = 5f;
    public ParticleSystem m4muzzleFlash;
    private bool isReloading = false;
    public Camera fpsCam;

    public Animator animator;

    void Start()
    {
           currentAmmo = maxAmmo;
    }

    void OnEnable ()
    {
        isReloading = false;
        animator.SetBool("Reloading", false);
    }


    // Update is called once per frame
    void Update()
    {
        if (isReloading)
            return;

        if (currentAmmo <= 0)
        {
            StartCoroutine(Reload());
            return;
        }

        if (Input.GetButton("Fire1"))
        {
            Shoots();
        }

    }

    IEnumerator Reload()
    {
        isReloading = true;
        Debug.Log("Reloading...");

        animator.SetBool("Reloading", true);

        yield return new WaitForSeconds(reloadTime - .25f);
        animator.SetBool("Reloading", false);
        yield return new WaitForSeconds(.25f);

        currentAmmo = maxAmmo;
        isReloading = false;
    }

    void Shoots ()
    {
        m4muzzleFlash.Play();

        currentAmmo--;

        RaycastHit hit;
        if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
        {
            Debug.Log(hit.transform.name);

            Target target = hit.transform.GetComponent<Target>();
            if (target != null)
            {
                target.TakeDamage(damage);
            }

            if (hit.rigidbody != null)
            {
                hit.rigidbody.AddForce(-hit.normal * impactforce);
            }
        }
    }
}

What’s the actual problem with the code? Seems roughly okay on a quick look. You should describe specifically what isn’t working. Otherwise maybe you’ll just get comments like, “Change the ‘20’ to ‘30’, that should do it…”

currentammo = 30; put that in void start().

Sorry I completely forgot to say what was wrong, I need to alter my code so that I can hold down the fire1 button and it fires at a steady rate

I just did that but i seem to keep reloading every 6-10 bullets for some reason

One approach is to declare a private float variable in your class called _lastShotTime, or something like that. When you actually fire the gun, set _lastShotTime to Time.timeSinceLevelLoad. Now, right at the beginning of your Shoots() method, check whether (Time.timeSinceLevelLoad - _lastShotTime) is greater than some constant firing rate. If it’s not, you return, and you don’t fire anything. But if enough time has passed, you proceed with shooting.

Is this right? Sorry if it isn’t i’m kinda new to C#
Right Now its giving me an error that float does not contain a definition for ‘timeSinceLevelLoad’

using UnityEngine;
using System.Collections;

public class m4Gun : MonoBehaviour
{

    public float damage = 20f;
    public float range = 100f;
    public float impactforce = 30f;

    public int maxAmmo = 30;
    public int currentAmmo;
    public float reloadTime = 5f;
    public ParticleSystem m4muzzleFlash;
    private bool isReloading = false;
    public Camera fpsCam;
    private float _lastShotTime;

    public Animator animator;

    void Start()
    {
           currentAmmo = 30;
    }

    void OnEnable ()
    {
        isReloading = false;
        animator.SetBool("Reloading", false);
    }


    // Update is called once per frame
    void Update()
    {
        if (isReloading)
            return;

        if (currentAmmo <= 0)
        {
            StartCoroutine(Reload());
            return;
        }

        if (Input.GetButton("Fire1"))
        {
            if (_lastShotTime.timeSinceLevelLoad - _lastShotTime > 0.25f)
                return;
            else
                _lastShotTime = _lastShotTime.timeSinceLevelLoad;
                Shoots();
        }

    }

    IEnumerator Reload()
    {
        isReloading = true;
        Debug.Log("Reloading...");

        animator.SetBool("Reloading", true);

        yield return new WaitForSeconds(reloadTime - .25f);
        animator.SetBool("Reloading", false);
        yield return new WaitForSeconds(.25f);

        currentAmmo = maxAmmo;
        isReloading = false;
    }

    void Shoots ()
    {
        m4muzzleFlash.Play();

        currentAmmo--;

        RaycastHit hit;
        if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
        {
            Debug.Log(hit.transform.name);

            Target target = hit.transform.GetComponent<Target>();
            if (target != null)
            {
                target.TakeDamage(damage);
            }

            if (hit.rigidbody != null)
            {
                hit.rigidbody.AddForce(-hit.normal * impactforce);
            }
        }
    }
}

‘Time’ is a special class in Unity. ‘Time.timeSinceLevelLoad’ gets the number of seconds since the level was loaded. You can’t call ‘timeSinceLevelLoad’ on just anything.

You’ve also got the logic a little reversed. You should return if the value is < 0.25f, not > 0.25f.

And most of all, you’ve completely broken your code due to your lack of curly braces. If you don’t use curly braces with an if/else, then only the immediate next line gets included in the if/else. So, in the case of your ‘else’, since you didn’t use curly braces, the “Shoots()” call isn’t part of the if/else at all, and it will be called regardless of the shot timer you set up.

My suggestion is to just always use curly braces to avoid these kinds of simple (but easy to make) mistakes, until you’re enough of a rockstar developer that you start to have strong opinions about curly braces.

Anyway, the following is probably correct:

        if (Input.GetButton("Fire1"))
        {
            if (Time.timeSinceLevelLoad - _lastShotTime < 0.25f) {
                return;
            } else {
                _lastShotTime = Time.timeSinceLevelLoad;
                Shoots();
            }
        }
1 Like

Ok i’ll quickly try that and get back to you
Thanks

Thankyou I just tried it and it worked
Thankyou so much!!

1 Like