我在使用倒数计时器功能时出现问题。在我的GameManager脚本中,我检查场景名称并检查空闲使用情况(没有鼠标移动/没有点击),并在我的CountdownTimer脚本中启动一个函数,该函数使用函数StartPreCountTimer()倒计时空闲时间量。一旦该计时器达到零,它就会实例化一个倒计时对话框并启动IEnumerator RunTimer(),用户可以取消继续播放或让它达到零,此时游戏重置并返回到介绍屏幕。
我遇到的问题是在preount步骤。 GameManager脚本每帧保持调用StartPreCountTimer(),这显然可以防止倒计时完成,因为它会重新启动每一帧。我该如何解决?如何从Update中调用该函数一次?
GameManager脚本
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public static GameManager gameManagerInstance = null; // Create Singleton
public GameObject loader;
public GameObject countdownTimer;
public Color defaultBackgroundColor;
public Object startingScene;
public GameObject timeOutWarningDialog;
public float countdownLength;
public float countdownDelay;
private Vector3 prevMousePosition;
private CountdownTimer countdownInstance;
private Scene currentScene;
private GameObject gameManager;
private GameObject canvas;
public static string animalDataFilePathJSON;
public static string animalDataFilePathTex;
void Awake()
{
if (gameManagerInstance == null)
gameManagerInstance = this;
else if (gameManagerInstance != null)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
gameManager = GameObject.FindGameObjectWithTag("GameManager");
// get and store JSON and Tex filepaths defined in Loader script
animalDataFilePathJSON = GameObject.FindGameObjectWithTag("Loader").GetComponent<Loader>().animalDataFilePathJSON;
animalDataFilePathTex = GameObject.FindGameObjectWithTag("Loader").GetComponent<Loader>().animalDataFilePathTex;
}
void Start()
{
prevMousePosition = Input.mousePosition;
currentScene = SceneManager.GetActiveScene();
countdownInstance = countdownTimer.GetComponent<CountdownTimer>(); // Create an instance of CountdownTimer
}
void Update()
{
currentScene = SceneManager.GetActiveScene();
if (currentScene.name != startingScene.name)
{
countdownInstance.StartPreCountTimer(); // Start Pre-count Timer
if (Input.GetMouseButtonDown(0) || Input.mousePosition != prevMousePosition)
{
countdownInstance.StartPreCountTimer(); // Start Pre-count Timer
if (timeOutWarningDialog != null)
timeOutWarningDialog.SetActive(false);
}
prevMousePosition = Input.mousePosition;
}
}
}
CountdownTimer脚本
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class CountdownTimer : MonoBehaviour {
public GameObject timeOutWarningDialog;
public float countdownLength;
public float countdownDelay;
public Object startingScene;
private float countdownInterval = 1;
private GameObject countdownTimer;
private IEnumerator counter;
private Button stopCountButton;
private Text timerTextField;
private GameObject timerInstance;
private GameObject canvas;
// 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[2]; // 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)
{
counter = RunTimer(countdownLength); // create new reference to counter, resets countdown to countdownLength
StartCoroutine(counter);
}
}
IEnumerator RunTimer(float seconds)
{
float s = seconds;
while (s > -1)
{
if (timerTextField != null)
timerTextField.text = s.ToString();
yield return new WaitForSeconds(countdownInterval);
s -= countdownInterval;
}
if (s == -1)
{
RestartGame();
}
}
void StopTimer()
{
StopCoroutine(counter);
Destroy(timerInstance);
}
void RestartGame()
{
SceneManager.LoadScene(startingScene.name);
}
}