简体   繁体   中英

Unity2D C# Reloading progress bar not working propertly

重新加载栏问题

So I'm making a top-down tank shooter game and I want to make a better reloading system than it was before. So I came to the idea that I need some king of progress bar. I knew how to make it so I started doing it. The problem is that it doesn't work properly. As I show in the .gif above, the progress bar don't go down when you shoot second time. Because I'm new to unity, I still don't know everything very good. So I came here, maybe someone could help.

EDIT: I just found another problem and maybe an answer why I have this problem. The second time my script tries to reload, my "needTimer" bool is false, thus the progress bar is not going down when it's false. The new question would be why it becomes false instead of true? My reloading script:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class Reload : MonoBehaviour {

    public float ammo;
    public Image progress;
    public bool alreadyReloading;
    public bool needTimer;

    void Start () {
        alreadyReloading = false;
    }
    IEnumerator needtimertime(){
        yield return new WaitForSeconds (6.5f);
        needTimer = false;
    }
    IEnumerator uztaisyt(){
        Debug.Log ("REEELOUUUDING!");
        yield return new WaitForSeconds(6.5f);
        ammo += 1;
        alreadyReloading = false;
    }

    void Update () {
        if (needTimer == true) {
            timer ("");
        }
        if (ammo < 5) {
            if(alreadyReloading == false){
                needTimer = true;
                StartCoroutine(uztaisyt());
                alreadyReloading = true;
            }
        }
        if (progress.fillAmount <= 0) {
            progress.fillAmount = 1.0f; 
        }
    }

    void timer(string tipas){
        progress.fillAmount -=  Time.deltaTime / 6.5f;
        StartCoroutine (needtimertime ());
    }
}

When you start the uztaisyt() as a coroutine after shooting the first time (in the animation), needTimer is set to true and in the next Update() call, the needtimertime() coroutine will start. Since both the uztaisyt() and needtimertime() have identical 6.5 second waits, they will not both return on the same frame update because needtimertime() will always be started in the next frame after uztaisyt() . And, since there is no guarantee of the time interval between Update() calls, (see Time and Frame Managment ), this interval may be more than expected and needtimertime() could return false in the frame right after uztaisyt() is called after firing the second time.

To ensure that the needtimertime() is always started (if not already running) immediately following a call for uztaisyt() (and called within the same frame update), you could try the following update to Reload script, (basically changes to the Update() method and when/how _isTimerRunning is set).

public class Reload : MonoBehaviour {

  public float ammo;
  public Image progress;

  private bool _alreadyReloading;
  private bool _isTimerRunning;

  void Start () {
      _alreadyReloading = false;
      _isTimerRunning = false;
  }

  IEnumerator needtimertime(){
      yield return new WaitForSeconds (6.5f);
      _needTimer = false;
  }

  IEnumerator uztaisyt(){
      Debug.Log ("REEELOUUUDING!");
      yield return new WaitForSeconds(6.5f);
      ammo += 1;
      _alreadyReloading = false;
  }

  void Update () {
      if (ammo < 5) {
          if(_alreadyReloading == false){                                        
              StartCoroutine(uztaisyt());
              _alreadyReloading = true;

              //this will check for and start the progress bar timer in the same udate call
              //so both coroutines finish on the same frame update
              if(!_isTimerRunning){
                _isTimerRunning = true;
                timer ("");
              }
          }
      }
      if (progress.fillAmount <= 0) {
          progress.fillAmount = 1.0f; 
      }
  }

  void timer(string tipas){
      progress.fillAmount -=  Time.deltaTime / 6.5f;
      StartCoroutine (needtimertime ());
  }
}

I found my problem and fixed it. The problem was that needTimer was becoming false. So I found where and removed it.

my new code:

using UnityEngine;

using UnityEngine.UI; using System.Collections;

public class Reload : MonoBehaviour {

public float ammo;
public Image progress;
public bool alreadyReloading;
public bool needTimer;

void Start () {
    alreadyReloading = false;
    needTimer = false;
}

IEnumerator uztaisyt(){
    Debug.Log ("REEELOUUUDING!");
    yield return new WaitForSeconds(6.5f);
    ammo += 1;
    alreadyReloading = false;
}

void Update () {
    if (ammo < 5.0f) {
        if(alreadyReloading == false){
            progress.fillAmount = 1.0f;
            needTimer = true;
            StartCoroutine(uztaisyt());
            alreadyReloading = true;
        }
        if (needTimer == true) {
            timer ("");
        }
    }
}

void timer(string tipas){
    progress.fillAmount -=  Time.deltaTime / 6.5f;
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM