我的倒计时器发生了一些奇怪的事情,我卡住了。我将一个数字传递给我的计时器(15秒),它从15开始,然后跳到0,然后从那里倒数:0,-1,-2,-3……我在这里做错了什么?
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class CountdownTimer : MonoBehaviour
{
float seconds;
public Text timerText;
public void Update()
{
seconds -= Time.deltaTime;
if (timerText != null)
{
timerText.text = Mathf.Round(seconds).ToString();
Debug.Log (Mathf.Round(seconds));
}
}
}我从另一个脚本中的函数调用倒计时脚本,如下所示:
void ShowRestartWarning()
{
//Debug.Log("Restart Warning Dialog");
canvas = GameObject.FindGameObjectWithTag("Canvas");
timerInstance = Instantiate(timeOutWarningDialog);
timerInstance.transform.SetParent(canvas.transform, false);
timerInstance.SetActive(true);
CountdownTimer countdownTimer = timeOutWarningDialog.GetComponent<CountdownTimer>();
countdownTimer.Update();
CancelInvoke();
Invoke("RestartGame", countdownLength);
}发布于 2017-06-13 06:18:19
尝试使用协程而不是Update函数,这样您就可以随时启动和停止它。
public Text timerText;
public void Start(int seconds)
{
StartCoroutine("RunTimer", seconds);
}
IEnumerator RunTimer(int seconds)
{
while (seconds > 0)
{
if (timerText != null)
{
timerText.text = seconds.ToString();
Debug.Log (seconds);
}
yield return new WaitForSeconds(1);
seconds -= 1;
}
}发布于 2017-06-13 13:12:00
public class CountdownTimer : MonoBehaviour
{
float seconds;
public Text timerText;
public void Update()
{
seconds -= Time.deltaTime;
if (timerText != null)
{
timerText.text = Mathf.Round(seconds).ToString();
Debug.Log (Mathf.Round(seconds));
}
}
}首先,被激活的MonoBehaviour中的Update()方法将在每一帧中被调用(更多信息在这里:Execution Order of Event Functions)
现在,在您的脚本中有两个变量。首先是私有seconds,然后是公共timerText。为什么timerText是公开的?如果该变量未被另一个类使用,则应为private。
现在该问了;但是我该如何在编辑器中附加Text组件呢?那么,您应该使用SerializeField。
现在我认为错误是您为Text组件赋了一些值。但是,您的变量seconds默认情况下为零。(您正在声明一个不带任何值的浮点数,默认情况下它将被initialized为0f)。
因此,在第一帧中,文本组件将显示初始值,假设为15。但在第一次调用Update()时,行seconds -= Time.deltaTime it将类似于seconds = 0f - Time.deltaTime;,然后timerText它将被更新为这个新的almost zero值。
你能做什么?在Update调用之前,可以使用另一个事件函数Awake为变量设置一些值。
如果你想使用timerText的值,你可以这样做:
public class CountdownTimer : MonoBehaviour
{
private float seconds;
[SerializeField]
private Text timerText;
private void Awake()
{
if (!string.isNullOrEmpty(timerText))
{
seconds = float.Parse(timerText.text);
}
}
// Yep, Event Functions can be private and Unity will `call` them anyways
private void Update()
{
seconds -= Time.deltaTime;
if (timerText != null)
{
timerText.text = Mathf.Round(seconds).ToString();
Debug.Log (Mathf.Round(seconds));
}
}
}https://stackoverflow.com/questions/44500002
复制相似问题