- Home /
not losing ammo when shooting
i have a script that shots raycasts, and there's a function that reloads (3 seconds) and after those 3 seconds are up, the player has unlimited ammo for a short amount of time. The currentAmmo variable was not changing. I need to fix this.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class M4A1Gun : MonoBehaviour {
public GameObject weepons;
public Camera fpsCam;
public ParticleSystem muzzleFlash;
public GameObject impactEffect;
public GameObject bloodHit;
public Animator anim;
public AudioSource shot;
public AudioSource reloadSound;
public float range = 100f;
public float damage = 10f;
public float fireRate = 15f;
public int maxAmmo = 30;
public int currentAmmo;
public float reloadTime = 3f;
private bool isReloading = false;
private float nextTimeToFire = 0f;
private float nextTimeToReload = 0f;
// Use this for initialization
void Start ()
{
currentAmmo = maxAmmo;
}
// Update is called once per frame
void Update ()
{
if (weepons.GetComponent<Weapons>().selectedWeaopon == 0f)
{
Gun();
}
if (isReloading == true && Time.time >= nextTimeToReload)
{
nextTimeToReload = Time.time + 15f / reloadTime;
ReloadSound();
}
}
IEnumerator Reload ()
{
isReloading = true;
Debug.Log("Reloading");
anim.SetBool("reloading", true);
this.GetComponent<M4A1anim>().shooting = false;
yield return new WaitForSeconds(reloadTime);
currentAmmo = maxAmmo;
isReloading = false;
anim.SetBool("reloading", false);
}
void ReloadSound()
{
reloadSound.Play();
}
void Gun()
{
if (currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
if (isReloading)
return;
if (Input.GetButton("Fire1") && Time.time >= nextTimeToFire)
{
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
}
if (Input.GetButtonUp("Fire1"))
{
this.GetComponent<M4A1anim>().shooting = false;
}
if (Input.GetButtonDown("Fire1"))
{
this.GetComponent<M4A1anim>().shooting = true;
}
}
void Shoot ()
{
muzzleFlash.Play();
shot.Play();
currentAmmo--;
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
WeebTarget target = hit.transform.GetComponent<WeebTarget>();
if (target != null)
{
target.TakeDamage(damage);
}
GameObject impactGO = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(impactGO, 2f);
if (hit.rigidbody != null)
{
GameObject bloodGO = Instantiate(bloodHit, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(bloodGO, 2f);
}
}
}
}
Answer by highpockets · Apr 04, 2019 at 08:08 AM
I believe you are starting multiple coroutines, I changed your code to check if isReloading is false before you start the coroutine. So, you will start one coroutine and not one every frame for those three seconds while isReloading is true.
void Gun()
{
if (currentAmmo <= 0 && !isReloading)
{
StartCoroutine(Reload());
return;
}
if (isReloading)
return;
if (Input.GetButton("Fire1") && Time.time >= nextTimeToFire)
{
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
}
if (Input.GetButtonUp("Fire1"))
{
this.GetComponent<M4A1anim>().shooting = false;
}
if (Input.GetButtonDown("Fire1"))
{
this.GetComponent<M4A1anim>().shooting = true;
}
}
When you have 0 currentAmmo, you were calling Reload() on that frame and every other frame until the 3 seconds were up. 3 seconds * frames per second of your game = how many Reload() coroutines you started and it wouldn't have finished with all coroutines until after an additional 3 seconds, so you would have had 3 seconds of infinite ammo until the last coroutine set it to 30 and then things go back to normal. If you only want one coroutine to start, you should have a bool or a state that tells you if the coroutine is running already.
Your answer
Follow this Question
Related Questions
Trouble with Raycast shooting 1 Answer
Problems with a shooting script 1 Answer
Raycast origin random 0 Answers
How to make a gun in unity? 1 Answer
How to Fix a Guns Firing Script so it Doesn't Constantly Fire 3 Answers