【发布时间】:2017-12-26 18:27:21
【问题描述】:
我不确定为什么会发生这种情况,但我有一个倒计时计时器,它会在用户点击调用 StopTimerButton() 的按钮时触发并停止。但是即使我调用了 StopCoroutine,计时器也会继续倒计时,直到它达到零,然后调用 RestartGame()。我的代码中缺少什么?
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class CountdownTimer : MonoBehaviour
{
public static CountdownTimer countdownTimerInstance = null; // create singleton
public Object startingScene;
public GameObject timeOutWarningDialog;
public float preCountdownLength;
public float countdownLength;
private GameObject timerDialogBoxInstance;
private GameObject timerDialogCountdownText;
private Text timerDialogCountdownTextTarget;
private GameObject canvas;
private IEnumerator warningCounter;
private IEnumerator preCounter;
private Button stopCountButton;
private float countdownInterval = 1.0f;
private bool preCountActive;
private bool warningCountActive;
void Awake()
{
ResetCountStates();
if (countdownTimerInstance == null)
countdownTimerInstance = this;
else if (countdownTimerInstance != null)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
}
void Update()
{
bool userActive = GameManager.userActive;
bool onIntroScreen = GameManager.onIntroScreen;
if (!userActive && !onIntroScreen && !preCountActive)
StartPreCountTimer(preCountdownLength);
else if (userActive && !onIntroScreen && preCountActive)
StopPreCountTimer();
}
void StartPreCountTimer(float length)
{
preCountActive = true;
preCounter = RunTimer(length);
StartCoroutine(preCounter);
Debug.Log("PreCount Started");
}
void StopPreCountTimer()
{
preCountActive = false;
StopCoroutine(preCounter);
Debug.Log("PreCount Stopped");
}
void WarningDialog(float length)
{
preCountActive = false;
warningCountActive = true;
canvas = GameObject.FindGameObjectWithTag("Canvas");
timerDialogBoxInstance = Instantiate(timeOutWarningDialog); // instantiate timeout warning dialog
timerDialogBoxInstance.transform.SetParent(canvas.transform, false);
timerDialogBoxInstance.SetActive(true);
timerDialogCountdownText = GameObject.FindGameObjectWithTag("CountdownText"); // get reference to countdown text GO
timerDialogCountdownTextTarget = timerDialogCountdownText.GetComponent<Text>(); // get countdown textfield component
stopCountButton = timerDialogBoxInstance.GetComponentInChildren<Button>(); // get reference to keep playing button
stopCountButton.onClick.AddListener(StopTimerButton); // add button listener
if (warningCountActive && !preCountActive && timerDialogBoxInstance != null)
{
warningCounter = RunTimer(length); // create new reference to counter, resets countdown to countdownLength
StartCoroutine(warningCounter);
}
}
IEnumerator RunTimer(float seconds)
{
// PRECOUNT TIMER
if (!warningCountActive)
{
float s = seconds;
while (s > 0)
{
yield return new WaitForSeconds(countdownInterval);
s -= countdownInterval;
Debug.Log("PreCount: " + s);
}
if (s == 0)
{
preCountActive = false;
warningCountActive = true;
WarningDialog(countdownLength);
}
}
// WARNING DIALOG TIMER
if (warningCountActive)
{
float s = seconds;
while (s > 0)
{
yield return new WaitForSeconds(countdownInterval);
if (timerDialogBoxInstance != null)
timerDialogCountdownTextTarget.text = s.ToString();
s -= countdownInterval;
Debug.Log("WarningCountdown: " + s);
}
if (s == 0)
if (timerDialogBoxInstance != null)
{
StopCoroutine(warningCounter);
Destroy(timerDialogBoxInstance);
RestartGame();
}
}
}
void StopTimerButton()
{
warningCountActive = false;
StopCoroutine(warningCounter);
if (timerDialogBoxInstance != null)
{
Destroy(timerDialogBoxInstance);
timerDialogBoxInstance = null;
}
Debug.Log("Restart Cancelled");
}
void ResetCountStates()
{
preCountActive = false;
warningCountActive = false;
}
void RestartGame()
{
ResetCountStates();
SceneManager.LoadScene(startingScene.name);
}
}
【问题讨论】:
-
什么时候调用
WarningDialog函数? -
在 PreCountTimer 达到零后(在 Runtimer 中)我调用 WarningDialog()。
-
如何使用
StopTimerButton函数启动要停止的计时器? -
我在 RunTimer 中使用以下行启动计时器:WarningDialog(countdownLength);
标签: c# unity3d timer coroutine