我不确定为什么会这样,但是我有一个倒计时器会触发,当用户点击一个调用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);
}
}
答案 0 :(得分:0)
脚本太长,无法找出问题,但我注意到可能存在问题。
在WarningDialog
函数中,查看以下代码块:
if (warningCountActive && !preCountActive && timerDialogBoxInstance != null)
{
warningCounter = RunTimer(length); // create new reference to counter, resets countdown to countdownLength
StartCoroutine(warningCounter);
}
StopTimerButton()
函数可能无法正常工作,因为每次RunTimer
函数仍在运行且您调用WarningDialog
函数时,协程函数引用名为warningCounter
丢失是因为当你warningCounter = RunTimer(length);
时被覆盖。
您必须将warningCounter = RunTimer(length);
移至Start()
功能,以便warningCounter
仅初始化一次。