寫計時相關功能時,使用 float 變數,在每個 Update()
加上或減去 deltaTime
,是不準確的做法。
因為 float 使用在比較大的數字的時候,用來儲存小數的位數就變少了,也就是說,加減的誤差變大。導致加減像是 deltaTime
這種很小的數值時,小數點就被誤差洗掉了,並導致計算不精準的狀況。當然,如果數字夠小,可能感受不出差別。
我自己簡單的實測一次:使用倖存者類型的 30 分鐘(1800 秒)來倒數計時。實際花費的時間是 1806.942 秒,30 分鐘就會有將近 7 秒的誤差。要注意時間和誤差不是正比關係,是根據整數佔了幾個位元來決定的。
正確的做法應該是在計時器開始的時候,用 Time.time
紀錄開始的時間,需要時間的時候就用當前的時間與開始的時間做比對。
using TMPro;
using UnityEngine;
public class Timer : MonoBehaviour
{
[SerializeField]
private TMP_Text _timeText;
private bool _isRunning = false;
private float _startTime;
private void Update()
{
if (!_isRunning)
{
if (Input.GetKeyDown(KeyCode.Space))
{
_isRunning = true;
_startTime = Time.time;
}
}
if (_isRunning)
{
float elapsedTime = Time.time - _startTime;
int minutes = Mathf.FloorToInt(elapsedTime / 60);
int seconds = Mathf.FloorToInt(elapsedTime % 60);
_timeText.text = $"{minutes:00}:{seconds:00}";
}
}
}