【问题标题】:Reset countdown time after StopCoroutineStopCoroutine 后重置倒计时时间
【发布时间】:2017-06-14 12:55:14
【问题描述】:

我无法弄清楚如何重置计时器的不活动倒计时。我正在使用协程来处理倒计时,然后使用 StopCoroutine 通过按下按钮来停止倒计时。但是,当倒计时对话框恢复并重新开始时(在不活动后),计数从之前停止的值开始。每次我的计数器实例化时,如何将计数重置为从完整的倒计时开始?

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

public class GameManager : MonoBehaviour 
{
    public static GameManager gameManagerInstance = null; // Create Singleton
    public Color defaultBackgroundColor;                 
    public Object startingScene;
    public GameObject timeOutWarningDialog;

    private float countdownLength = 15;
    private float countdownDelay = 5;
    private float countdownInterval = 1;
    private IEnumerator counter;
    private Button stopCountButton;
    private Text timerTextField;
    private Vector3 prevMousePosition;
    private Scene currentScene;
    private GameObject gameManager;
    private GameObject canvas;
    private GameObject timerInstance;

    void Awake()
    {
        if (gameManagerInstance == null)
            gameManagerInstance = this;
        else if (gameManagerInstance != null)
            Destroy(gameObject);
        DontDestroyOnLoad(gameObject);
        gameManager = GameObject.FindGameObjectWithTag("GameManager");
    }

    void Start()
    {
        counter = RunTimer(countdownLength);
        prevMousePosition = Input.mousePosition;
        currentScene = SceneManager.GetActiveScene();
    }

    void Update()
    {
        if (Input.anyKeyDown || Input.mousePosition != prevMousePosition)
        {
            currentScene = SceneManager.GetActiveScene();

            if (currentScene.name != startingScene.name)
                StartPreCountTimer();
                if (timeOutWarningDialog != null)
                    timeOutWarningDialog.SetActive(false);
        }
        prevMousePosition = Input.mousePosition;
    }

    // GAME TIMER

    public void StartPreCountTimer()
    {
        CancelInvoke();
        if (GameObject.FindGameObjectWithTag("Timer") == null)
            Invoke("ShowRestartWarning", countdownDelay);
    }

    void ShowRestartWarning()
    {
        canvas = GameObject.FindGameObjectWithTag("Canvas");

        timerInstance = Instantiate(timeOutWarningDialog); // instantiate timeout warning dialog
        timerInstance.transform.SetParent(canvas.transform, false);
        timerInstance.SetActive(true);

        Text[] textFields = timerInstance.GetComponentsInChildren<Text>(true); // get reference to timer textfields
        timerTextField = textFields[1]; // access and assign countdown textfield

        stopCountButton = timerInstance.GetComponentInChildren<Button>(); // get reference to keep playing button
        stopCountButton.onClick.AddListener(StopTimer); // add button listener

        if (timerInstance.activeSelf == true)
            StartCoroutine(counter);
    }

    IEnumerator RunTimer(float seconds)
    {
        float s = seconds;
        while (s > 0)
        {
            if (timerTextField != null)
                timerTextField.text = s.ToString();
            yield return new WaitForSeconds(countdownInterval);
            s -= 1;
        }

        if (s == 0)
        {
            RestartGame();
        }
    }

    void StopTimer()
    {
        StopCoroutine(counter);
        Destroy(timerInstance);
    }

    void RestartGame()
    {
        SceneManager.LoadScene(startingScene.name);
    }
}

【问题讨论】:

  • 用while来实现定时器,效率很低!
  • @David 你建议我怎么做?
  • @David 也对您的答案感兴趣:尽管在协程中使用 while 循环是最简单的方法(我个人使用一个计时器 float 变量,每帧都在/递减使用Time.deltaTime)。

标签: c# unity3d counter countdown


【解决方案1】:

如果您想重置(这不是正确的重置,而只是一个新的协程)协程内的代码,则需要为 counter 分配一个新的引用。

IE:

void StopTimer() {
    StopCoroutine(counter);
    counter = RunTimer(countdownLength);
    Destroy(timerInstance);
}

【讨论】:

  • 太好了,谢谢!所以如果我每次都创建一个新的 counter 引用,当我 Destroy(timerInstance) 时旧的引用会被破坏吗?
  • 抱歉,我把对counter 的新引用放错了位置,已编辑以更正错误。总是最好在 StopCoroutine 之后给出新的引用,以表明其意图是“重置”该协程。
  • @greyBow 如果它解决了您的问题,请不要忘记接受答案。如果没有,请注释掉缺少的内容。
猜你喜欢
  • 2015-05-11
  • 1970-01-01
  • 2017-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-10
  • 1970-01-01
相关资源
最近更新 更多