Search Unity

Reloading issue

Discussion in 'Scripting' started by WaterP, Aug 14, 2017.

  1. WaterP

    WaterP

    Joined:
    Jun 21, 2017
    Posts:
    1
    I'm new to unity so it may be obvious just don't get angry or whatever.
    so when making a gun script I seem to sometimes have the reload animation work and sometimes not. if someone could tell me how to fix it I would be greatly appreciated :D

    Script:
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;

    public class Gun_Script : MonoBehaviour {

    public float damage = 10f;
    public float range = 100f;
    public float impactForce = 30f;
    public float fireRate = 15f;
    public AudioSource gun;

    public int maxAmmo = 10;
    private int currentAmmo;
    public float reloadTime = 1f;
    private bool isReloading = false;
    public Animator animator;
    public bool auto = true;
    public float shootTime = .30f;
    public bool shooting = false;
    public bool reloading = false;
    public Text ammo;
    public float Maxhealth = 100f;
    public Text Health;
    public float health = 100f;
    public Slider healthBar;

    public Camera fpsCam;

    private float nextTimeToFire = 0f;

    void Start()
    {
    currentAmmo = maxAmmo;
    ammo.text = "Ammo : " + currentAmmo + "/" + maxAmmo;
    Health.text = "Health : " + health + "/" + Maxhealth;
    healthBar.value = currentAmmo;
    }

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

    // Update is called once per frame
    void Update()
    {
    Health.text = "Health : " + health + "/" + Maxhealth;
    ammo.text = "Ammo : " + currentAmmo + "/" + maxAmmo;
    if (Input.GetKeyDown("b"))
    {
    if (auto == true)
    auto = false;
    else
    auto = true;
    }

    if (Input.GetKeyDown("r") && currentAmmo < maxAmmo)
    {
    StartCoroutine(Reload());
    return;
    }

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

    if (isReloading)
    return;
    if (Input.GetButton("Fire1") && Time.time >= nextTimeToFire && auto == true)
    {
    nextTimeToFire = Time.time + 1f / fireRate;
    Shoot();
    }

    if (Input.GetButtonDown("Fire1") && Time.time >= nextTimeToFire && auto == false)
    {
    nextTimeToFire = Time.time + 1f / fireRate;
    Shoot();
    }
    }

    IEnumerator Reload ()
    {
    isReloading = true;
    animator.SetBool("isReloading", true);
    yield return new WaitForSeconds(reloadTime - .25f);

    animator.SetBool("isReloading", false);

    yield return new WaitForSeconds(.25f);

    currentAmmo = maxAmmo;
    isReloading = false;
    }

    void Shoot ()
    {
    currentAmmo--;
    gun.Play();
    shooting = true;
    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);
    hit.rigidbody.AddForce(-hit.normal * impactForce);
    }
    }
    }
    }
     
  2. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    Start off by helping everyone diagnose your code a bit better by using code tags in your post above. That process is explained here: https://forum.unity3d.com/threads/using-code-tags-properly.143875/

    I haven't looked too much at your code, but my first guess is that I wonder if maybe your coroutine is being called multiple times. That might not be the cause of your problem, but looking at things quickly, it does look like your coroutine can be triggered many times, and WOULD trigger many times, especially if your player runs out of ammo (unless I'm missing something), and that would be bad no matter what. So fix that. Maybe use that reloading flag.. set it immediately when a condition is hit to start reloading, and always check that.. for example:

    Code (csharp):
    1. if (!isReloading && Input.GetKeyDown("r") && currentAmmo < maxAmmo)
    2. {    
    3. ... do stuff
    4. }
    Further to that, I'd actually combine your two scenarios like so, so that they can't both get called in one update frame:
    Code (csharp):
    1. if (!isReloading && ( (Input.GetKeyDown("r") && currentAmmo < maxAmmo) || (currentAmmo <= 0) ))
    2. {  
    3. ... do stuff
    4. }
    Hopefully I got all the brackets correct above.. but the idea is, if you're not already reloading... AND..... you're either triggering the reload manually and you've used some bullets OR you're out of ammo.... do your reload.