Gun reload script issue

I have been working on an gun that when the player fires a round and if the int is below the max amount, the player can reload. The current script allows the player to reload, but only when current ammo is at 0. I would like to reload anytime after current ammo is below max ammo, but only add up to max ammo in the current ammo.

Would someone take a look and help me see where to make this happen? And perhaps how?

{
    public float damage = 10f;
    public float range = 100f;
    public float lightTime = 10f;
    public float holeTime = 10f;
    public float brassTime = 10f;
    public float fireRate = 15f;
    public float force = 30f;
    public float brassForce = 30f;
    public Camera fpsCam;
    public GameObject muzzleFlash;
    public GameObject impactEffect;
    public GameObject brassCasing;
    public Transform firespot;
    public Transform brass;
    public GameObject[] holes;
    public Animator anim;
    public AudioClip fire;
    public AudioClip reload;
    public AudioClip dryfire;
    public float volume;
    AudioSource audio;

    private float nextTimeToFire = 0f;

    public int maxHoldAmmo = 99;
    public int HoldAmmo = 99;
    public int maxAmmo = 30;
    public int currentAmmo = -1;
    public int clipAmmo = 30;

    public Text HoldAmmoText;
    public Text currentAmmoText;
    public bool NoPickUp = false;
    public bool canReload = false;

    private void Start()
    {
        audio = GetComponent<AudioSource>();
        if (currentAmmo == -1)
            currentAmmo = maxAmmo;
            currentAmmoText.text = currentAmmo.ToString();
            HoldAmmoText.text = HoldAmmo.ToString();
    }

    void OnEnable()
    {
        anim.SetBool("Reloading", false);
    }

    void Update ()
    {
        currentAmmoText.text = currentAmmo.ToString();
        HoldAmmoText.text = HoldAmmo.ToString();
        if(HoldAmmo == maxHoldAmmo)
        {
            NoPickUp = true;
        }
        else
        {
            NoPickUp = false;
        }

        if(currentAmmo <= maxAmmo)
        {
            canReload = true;
        }
        else
        {
            canReload = false;
        }

        if (maxAmmo <= 0 && currentAmmo <= 0)
        {
            return;
        }
        else
        {
            if (currentAmmo <= 0)
            {
                Reload();
                return;
            }
        }
if(Input.GetButton("Fire1") && Time.time >= nextTimeToFire)
        {
            anim.SetBool("Firing", true);
            anim.SetBool("Reloading", false);
            nextTimeToFire = Time.time + 1f / fireRate;
            Shoot();
        }
        else
        {
            anim.SetBool("Firing", false);
        }
}

    void Reload()
    {
        if(Input.GetButton("Fire2") && canReload)
        {
            anim.SetBool("Reloading", true);
            audio.PlayOneShot(reload, volume);
            currentAmmo = maxAmmo;
            HoldAmmo -= maxAmmo;
            if(HoldAmmo <= maxAmmo)
            {
                maxAmmo = HoldAmmo;
                if (HoldAmmo <= 0)
                {
                    return;
                }
            }
            return;
        }
      
    }

    void Shoot()
    {
        currentAmmo--;
        RaycastHit hit;
        if(Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
        {
            Target target = hit.transform.GetComponent<Target>();
            if(target != null)
            {
                target.TakeDamage(damage);
            }
            if(hit.rigidbody != null)
            {
                hit.rigidbody.AddForce(-hit.normal * force);
            }

            GameObject impactGO = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
            Destroy(impactGO, lightTime);
            GameObject muzzleGO = Instantiate(muzzleFlash, firespot.transform.position, transform.rotation);
            Destroy(muzzleGO, lightTime);
            GameObject brassGO = Instantiate(brassCasing, brass.transform.position, transform.rotation);
            Rigidbody rbBrass = brassGO.GetComponent<Rigidbody>();
            rbBrass.AddForce(transform.right * force);
            Destroy(brassGO, brassTime);
            if (!target)
            {
                GameObject holeGO = Instantiate(holes[Random.Range(0, holes.Length)], hit.point, Quaternion.LookRotation(-hit.normal));
                Destroy(holeGO, holeTime);
            }
        }
        audio.PlayOneShot(fire, volume);
    }

    public void Ammo()
    {
        if(HoldAmmo <= maxHoldAmmo)
        {
            HoldAmmo += clipAmmo;
            NoPickUp = false;
        }
        if(HoldAmmo >= maxHoldAmmo)
        {
            HoldAmmo = maxHoldAmmo;
            NoPickUp = true;
        }
    }
}

Ok with a little more messing around I was able to get some things working. Still cannot reload between 0-29 though. Any help would be great!

using UnityEngine;
using UnityEngine.UI;

public class Gun : MonoBehaviour
{
    public float damage = 10f;
    public float range = 100f;
    public float lightTime = 10f;
    public float holeTime = 10f;
    public float brassTime = 10f;
    public float fireRate = 15f;
    public float force = 30f;
    public float brassForce = 30f;
    public Camera fpsCam;
    public GameObject muzzleFlash;
    public GameObject impactEffect;
    public GameObject brassCasing;
    public Transform firespot;
    public Transform brass;
    public GameObject[] holes;
    public Animator anim;
    public AudioClip fire;
    public AudioClip reload;
    public AudioClip dryfire;
    public float volume;
    AudioSource audio;

    private float nextTimeToFire = 0f;

    public int maxHoldAmmo = 99;
    public int HoldAmmo = 99;
    public int maxAmmo = 30;
    public int currentAmmo = -1;
    public int clipAmmo = 30;

    public Text HoldAmmoText;
    public Text currentAmmoText;
    public bool NoPickUp = false;
    public bool canReload = false;

    private void Start()
    {
        audio = GetComponent<AudioSource>();
        if (currentAmmo == -1)
            currentAmmo = maxAmmo;
            currentAmmoText.text = currentAmmo.ToString();
            HoldAmmoText.text = HoldAmmo.ToString();
    }

    void OnEnable()
    {
        anim.SetBool("Reloading", false);
    }

    void Update ()
    {

        currentAmmoText.text = currentAmmo.ToString();
        HoldAmmoText.text = HoldAmmo.ToString();
        if(HoldAmmo == maxHoldAmmo)
        {
            NoPickUp = true;
        }
        else
        {
            NoPickUp = false;
        }

        if(currentAmmo <= maxAmmo)
        {
            canReload = true;
        }
        else
        {
            canReload = false;
        }

        if (maxAmmo <= 0 && currentAmmo <= 0)
        {
            return;
        }
        else
        {
            if (currentAmmo <= 0)
            {
                Reload();
                return;
            }
        }
if(Input.GetButton("Fire1") && Time.time >= nextTimeToFire)
        {
            anim.SetBool("Firing", true);
            anim.SetBool("Reloading", false);
            nextTimeToFire = Time.time + 1f / fireRate;
            Shoot();
        }
        else
        {
            anim.SetBool("Firing", false);
        }
}

    void Reload()
    {
        if(Input.GetButton("Fire2") && canReload)
        {
            anim.SetBool("Reloading", true);
            audio.PlayOneShot(reload, volume);
            currentAmmo = maxAmmo;
            HoldAmmo -= maxAmmo;
            if(HoldAmmo <= maxAmmo)
            {
                maxAmmo = HoldAmmo;
                if (HoldAmmo <= 0)
                {
                    return;
                }
            }

            return;
        }
      
    }

    void Shoot()
    {
        currentAmmo--;
        RaycastHit hit;
        if(Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
        {
            Target target = hit.transform.GetComponent<Target>();
            if(target != null)
            {
                target.TakeDamage(damage);
            }
            if(hit.rigidbody != null)
            {
                hit.rigidbody.AddForce(-hit.normal * force);
            }

            GameObject impactGO = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
            Destroy(impactGO, lightTime);
            GameObject muzzleGO = Instantiate(muzzleFlash, firespot.transform.position, transform.rotation);
            Destroy(muzzleGO, lightTime);
            GameObject brassGO = Instantiate(brassCasing, brass.transform.position, transform.rotation);
            Rigidbody rbBrass = brassGO.GetComponent<Rigidbody>();
            rbBrass.AddForce(transform.right * force);
            Destroy(brassGO, brassTime);
            if (!target)
            {
                GameObject holeGO = Instantiate(holes[Random.Range(0, holes.Length)], hit.point, Quaternion.LookRotation(-hit.normal));
                Destroy(holeGO, holeTime);
            }
        }
        audio.PlayOneShot(fire, volume);
    }

    public void Ammo()
    {
        if(HoldAmmo <= maxHoldAmmo)
        {
            HoldAmmo += clipAmmo;
            NoPickUp = false;
        }
        if(HoldAmmo >= maxHoldAmmo)
        {
            HoldAmmo = maxHoldAmmo;
            NoPickUp = true;
        }


    }

    public void ForceReload()
    {
        maxAmmo = clipAmmo;
        anim.SetBool("Reloading", true);
        audio.PlayOneShot(reload, volume);
        currentAmmo = maxAmmo;
    }

}

Hey Starmind,

I believe the problem is in the Update method.
For the player to reload, you check if the player hits Mouse2 inside the Reload() method, but you only call Reload() method when currentAmmo is <= 0 at line 84.
If the currentAmmo is simply less, you only set canReload = true
So you should be able to just call the Reload method along with setting canReload to true at line 71.

Hope this helps!

1 Like

Thank you. I knew about the Update, but when I put it in, it didn’t work properly. The problem is when the player reloads, the reload is 30. So if say the player has a current ammo of 29 and a max ammo of 60, when reloading the current ammo will go to 30 and the max ammo will go to 30 for just one round. How do I stop it from doing this and only add what is needed to get to 30 for the current ammo. I think I am missing how to subtract properly around lines 111-112

Below is an updated script

using UnityEngine;
using UnityEngine.UI;

public class Gun : MonoBehaviour
{
    public float damage = 10f;
    public float range = 100f;
    public float lightTime = 10f;
    public float holeTime = 10f;
    public float brassTime = 10f;
    public float fireRate = 15f;
    public float force = 30f;
    public float brassForce = 30f;
    public Camera fpsCam;
    public GameObject muzzleFlash;
    public GameObject impactEffect;
    public GameObject brassCasing;
    public Transform firespot;
    public Transform brass;
    public GameObject[] holes;
    public Animator anim;
    public AudioClip fire;
    public AudioClip reload;
    public AudioClip dryfire;
    public float volume;
    AudioSource audio;

    private float nextTimeToFire = 0f;

    public int maxHoldAmmo = 99;
    public int HoldAmmo = 99;
    public int maxAmmo = 30;
    public int currentAmmo = -1;
    public int clipAmmo = 30;

    public Text HoldAmmoText;
    public Text currentAmmoText;
    public bool NoPickUp = false;
    public bool canReload = false;

    private void Start()
    {
        audio = GetComponent<AudioSource>();
        if (currentAmmo == -1)
            currentAmmo = maxAmmo;
            currentAmmoText.text = currentAmmo.ToString();
            HoldAmmoText.text = HoldAmmo.ToString();
    }

    void OnEnable()
    {
        anim.SetBool("Reloading", false);
    }

    void Update ()
    {

        currentAmmoText.text = currentAmmo.ToString();
        HoldAmmoText.text = HoldAmmo.ToString();
        if(HoldAmmo == maxHoldAmmo)
        {
            NoPickUp = true;
        }
        else
        {
            NoPickUp = false;
        }

        if(currentAmmo <= maxAmmo)
        {
            canReload = true;
        }
        if(currentAmmo == clipAmmo)
        {
             canReload = false;
        }

        if (maxAmmo <= 0 && currentAmmo <= 0)
        {
            return;
        }
        else
        {
            if (currentAmmo <= 0)
            {
                Reload();
                return;
            }
        }
if(Input.GetButton("Fire1") && Time.time >= nextTimeToFire)
        {
            anim.SetBool("Firing", true);
            anim.SetBool("Reloading", false);
            nextTimeToFire = Time.time + 1f / fireRate;
            Shoot();
        }
        else
        {
            anim.SetBool("Firing", false);
        }
      if(Input.GetButton("Fire2") && canReload)
        {
            if(currentAmmo == clipAmmo)
            {
                canReload = false;
            }
            if(currentAmmo <= maxAmmo)
            { 
               anim.SetBool("Reloading", true);
               audio.PlayOneShot(reload, volume);
               currentAmmo = maxAmmo;
               HoldAmmo -= maxAmmo;
            }
        }
}

    void Reload()
    {
        if(Input.GetButton("Fire2") && canReload)
        {
            anim.SetBool("Reloading", true);
            audio.PlayOneShot(reload, volume);
            currentAmmo = maxAmmo;
            HoldAmmo -= maxAmmo;
            if(HoldAmmo <= maxAmmo)
            {
                maxAmmo = HoldAmmo;
                if (HoldAmmo <= 0)
                {
                    return;
                }
            }

            return;
        }
   
    }

    void Shoot()
    {
        currentAmmo--;
        RaycastHit hit;
        if(Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
        {
            Target target = hit.transform.GetComponent<Target>();
            if(target != null)
            {
                target.TakeDamage(damage);
            }
            if(hit.rigidbody != null)
            {
                hit.rigidbody.AddForce(-hit.normal * force);
            }

            GameObject impactGO = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
            Destroy(impactGO, lightTime);
            GameObject muzzleGO = Instantiate(muzzleFlash, firespot.transform.position, transform.rotation);
            Destroy(muzzleGO, lightTime);
            GameObject brassGO = Instantiate(brassCasing, brass.transform.position, transform.rotation);
            Rigidbody rbBrass = brassGO.GetComponent<Rigidbody>();
            rbBrass.AddForce(transform.right * force);
            Destroy(brassGO, brassTime);
            if (!target)
            {
                GameObject holeGO = Instantiate(holes[Random.Range(0, holes.Length)], hit.point, Quaternion.LookRotation(-hit.normal));
                Destroy(holeGO, holeTime);
            }
        }
        audio.PlayOneShot(fire, volume);
    }

    public void Ammo()
    {
        if(HoldAmmo <= maxHoldAmmo)
        {
            HoldAmmo += clipAmmo;
            NoPickUp = false;
        }
        if(HoldAmmo >= maxHoldAmmo)
        {
            HoldAmmo = maxHoldAmmo;
            NoPickUp = true;
        }


    }

    public void ForceReload()
    {
        maxAmmo = clipAmmo;
        anim.SetBool("Reloading", true);
        audio.PlayOneShot(reload, volume);
        currentAmmo = maxAmmo;
    }

}

Oh, whoops, sorry I misunderstood your question then.
You could check for the difference between clipAmmo and currentAmmo, and then take that value, add it to the currentAmmo, and subtract it from HoldAmmo. For example:

int ammoDiff = clipAmmo - currentAmmo;
currentAmmo += ammoDiff;
HoldAmmo -= ammoDiff;

Say if we have 20 currentAmmo, and 30 for clipAmmo, it would set ammoDiff to 10(30 - 20). We then add ammoDiff to our currentAmmo(to reset us back to the original clipAmmo amount), and then we take away ammoDiff from HoldAmmo.

You’ll also want to replace the reloading on Lines 123-124.

That works great! One small problem, if I have say 20 current ammo and say 9 max ammo, when the player reloads it falls into the negative. Like the player now has 30 current ammo and -18 max ammo.
Now it will not allow the player to reload and will clear the negative when the current ammo reaches 0. Any way to fix that??

Ah yeah that’s something that I didn’t consider.

This is updated code from my previous answer, which makes use fo the Mathf.Clamp function.

int ammoDiff = clipAmmo - currentAmmo;
ammoDiff = Mathf.Clamp(ammoDiff, 0, HoldAmmo);
currentAmmo += ammoDiff;
HoldAmmo -= ammoDiff;

What this will do is clamp ammoDiff, ensuring it doesn’t exceed HoldAmmo. If it does exceed holdAmmo, it’ll be clamped to HoldAmmo(which is 9 in the scenario you gave.) Then it’ll just add 9 to currentAmmo, and subtract 9 from HoldAmmo.

Thank you for your help! That last bit helped me fix it and it is working great! Now to make to find a way to stick the bullet holes to a rigidbody that moves.

Little video of the project I am working on.

Here is the fixed script

using UnityEngine;
using UnityEngine.UI;

public class Gun : MonoBehaviour
{
    public float damage = 10f;
    public float range = 100f;
    public float lightTime = 10f;
    public float holeTime = 10f;
    public float brassTime = 10f;
    public float fireRate = 15f;
    public float force = 30f;
    public float brassForce = 30f;
    public Camera fpsCam;
    public GameObject muzzleFlash;
    public GameObject impactEffect;
    public GameObject brassCasing;
    public Transform firespot;
    public Transform brass;
    public GameObject[] holes;
    public Animator anim;
    public AudioClip fire;
    public AudioClip reload;
    public AudioClip dryfire;
    public float volume;
    AudioSource audio;

    private float nextTimeToFire = 0f;

    public int maxHoldAmmo = 99;
    public int HoldAmmo = 99;
    public int maxAmmo = 30;
    public int currentAmmo = -1;
    public int clipAmmo = 30;

    public Text HoldAmmoText;
    public Text currentAmmoText;
    public bool NoPickUp = false;
    public bool canReload = false;

    private void Start()
    {
      
        audio = GetComponent<AudioSource>();
        if (currentAmmo == -1)
            currentAmmo = maxAmmo;
            currentAmmoText.text = currentAmmo.ToString();
            HoldAmmoText.text = HoldAmmo.ToString();
    }

    void OnEnable()
    {
        anim.SetBool("Reloading", false);
    }

    void Update ()
    {
      
        currentAmmoText.text = currentAmmo.ToString();
        HoldAmmoText.text = HoldAmmo.ToString();
        if(HoldAmmo == maxHoldAmmo)
        {
            NoPickUp = true;
        }
        else
        {
            NoPickUp = false;
        }

        if(currentAmmo <= maxAmmo)
        {
            canReload = true;
        }
        if (currentAmmo == clipAmmo)
        {
            canReload = false;
        }

        if (maxAmmo <= 0 && currentAmmo <= 0)
        {
            HoldAmmo = 0;
            maxAmmo = 0;
            return;
        }
        else
        {
            if (currentAmmo <= 0)
            {
                Reload();
                return;
            }
        }
if(Input.GetButton("Fire1") && Time.time >= nextTimeToFire)
        {
            anim.SetBool("Firing", true);
            anim.SetBool("Reloading", false);
            nextTimeToFire = Time.time + 1f / fireRate;
            Shoot();
        }
        else
        {
            anim.SetBool("Firing", false);
        }
        if (Input.GetButton("Fire2") && canReload)
        {
            if(currentAmmo == clipAmmo)
            {
                canReload = false;
            }
            if(currentAmmo <= maxAmmo)
            {
                Reload();
            }
        }
    }

    void Reload()
    {
        if(Input.GetButton("Fire2") && canReload)
        {
            anim.SetBool("Reloading", true);
            audio.PlayOneShot(reload, volume);
            int ammoDiff = clipAmmo - currentAmmo;
            ammoDiff = Mathf.Clamp(ammoDiff, 0, HoldAmmo);
            currentAmmo += ammoDiff;
            HoldAmmo -= ammoDiff;
            if (ammoDiff == 0)
                maxAmmo = 0;
            if (HoldAmmo <= maxAmmo)
            {
                maxAmmo = HoldAmmo;
                if (HoldAmmo <= 0)
                {
                    maxAmmo = 0;
                    return;
                }
            }

            return;
        }
      
    }

    void Shoot()
    {
        currentAmmo--;
        RaycastHit hit;
        if(Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
        {
            Target target = hit.transform.GetComponent<Target>();
            if(target != null)
            {
                target.TakeDamage(damage);
            }
            if(hit.rigidbody != null)
            {
                hit.rigidbody.AddForce(-hit.normal * force);
            }

            GameObject impactGO = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
            Destroy(impactGO, lightTime);
            GameObject muzzleGO = Instantiate(muzzleFlash, firespot.transform.position, transform.rotation);
            Destroy(muzzleGO, lightTime);
            GameObject brassGO = Instantiate(brassCasing, brass.transform.position, transform.rotation);
            Rigidbody rbBrass = brassGO.GetComponent<Rigidbody>();
            rbBrass.AddForce(transform.right * force);
            Destroy(brassGO, brassTime);
            if (!target)
            {
                GameObject holeGO = Instantiate(holes[Random.Range(0, holes.Length)], hit.point, Quaternion.LookRotation(-hit.normal));
                Destroy(holeGO, holeTime);
            }
        }
        audio.PlayOneShot(fire, volume);
    }

    public void Ammo()
    {
        if(HoldAmmo <= maxHoldAmmo)
        {
            HoldAmmo += clipAmmo;
            NoPickUp = false;
        }
        if(HoldAmmo >= maxHoldAmmo)
        {
            HoldAmmo = maxHoldAmmo;
            NoPickUp = true;
        }


    }

    public void ForceReload()
    {
        maxAmmo = clipAmmo;
        anim.SetBool("Reloading", true);
        audio.PlayOneShot(reload, volume);
        currentAmmo = maxAmmo;
    }

}
1 Like