我可以创建一个倒计时计时器,而不把它放在更新功能
本文关键字:新功能 更新 计时器 创建 倒计时 一个 我可以 | 更新日期: 2023-09-27 18:07:00
我有一个倒计时脚本,我想传递几个参数,但我只知道如何在更新函数中使用计时器,更新不接受参数。如何在不使用Update的情况下实现这一点?这样做合适吗?
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class CountdownTimer : MonoBehaviour
{
float seconds;
float minutes;
public Text timerText;
public void startTimer(float m, float s)
{
minutes = m;
seconds = s;
Update ();
}
public void Update ()
{
if(seconds <= 0)
{
seconds = 59;
if(minutes >= 1)
{
minutes --;
}
else
{
minutes = 0;
seconds = 0;
// Show the time in whole seconds, "f0" removes decimal places
timerText.text = seconds.ToString("f0");
}
}
else
{
seconds -= Time.deltaTime;
}
if (Mathf.Round (seconds) <= 9)
{
timerText.text = seconds.ToString("f0");
}
}
}
如果您确实需要随时访问计时器的状态,那么类似的东西(尽管代码更简洁,逻辑更简单,参见我在评论中关于秒和分钟的提示)是可以的。基本上,累积增量时间来查看从计时器开始以来已经过去了多少时间。
如果你只需要等待计时器完成,那么还有Invoke
。
public class MyTimer : MonoBehaviour
{
public float Interval;
//Some events go here, maybe, to be fired when the timer changes states?
public void Restart()
{
CancelInvoke("Finished"); //In case it's already running.
Invoke("Finished", Interval); //Calls Finished() Interval seconds from now.
}
public void Finished()
{
//Fire your events.
}
}
您也可以选择每X秒触发一个Tick()
方法来访问当前经过的时间之类的东西,但在这种情况下,我将放弃协程并像您一样累积增量时间。
补充Alex M.的答案,还有InvokeRepeating方法,它类似于Invoke
,但反复调用目标方法。你可以这样使用:
void Start()
{
InvokeRepeating("Tick", 0f, 1.0f);
}
private void Tick()
{
// do some stuff here every second, e.g. accumulate time in some variable
}
InvokeRepeating
的第二个参数是第一次调用Tick应该发生的延迟,第三个参数是调用Tick的重复周期。
如果你想为一个被反复调用的方法插入参数(比如每X秒),你需要查找协程。它们可以这样使用:
void Start()
{
StartCoroutine(DoStuffRepeatedly(float param1, bool param2,..., repeatRate));
}
private IEnumerator DoStuffRepeatedly(float param1, bool param2,..., repeatRate) {
while(someCondition) {
// do some stuff here
yield return new WaitForSeconds(repeatRate);
}
}
我通过这种方式完成了我需要做的事情:
public class GameSetup : MonoBehaviour
{
void Start()
{
prevMousePosition = Input.mousePosition;
}
void Update()
{
if(Input.anyKeyDown || Input.mousePosition != prevMousePosition)
{
StartGameTimer();
timeOutWarning.SetActive(false);
}
prevMousePosition = Input.mousePosition;
}
void StartGameTimer()
{
CancelInvoke ();
Invoke ("ShowRestartWarning", timeUntilRestartWarning);
}
void ShowRestartWarning()
{
GameObject gameController = GameObject.FindGameObjectWithTag("gc"); // First, find the GameObject
CountdownTimer countdownTimer = gameController.GetComponent<CountdownTimer>(); // Then, access the Script in the GameObject
countdownTimer.startTimer(countdownLength); // Finally, call the Script method
timeOutWarning.SetActive(true);
CancelInvoke ();
Invoke ("RestartGame", countdownLength);
}
void RestartGame()
{
Application.LoadLevel(Application.loadedLevel);
Debug.Log("Game Restarted");
}
}
public class CountdownTimer : MonoBehaviour
{
float seconds;
public Text timerText;
public void startTimer(float s)
{
seconds = s;
Update ();
}
public void Update ()
{
seconds -= Time.deltaTime;
timerText.text = seconds.ToString("f0");
}
}