You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity(C#)中使用Time.deltaTime仍出现倒计时变慢甚至停止问题

倒计时大数值变慢/停止问题修复

问题

作为编程新手,我在Unity里实现天/时/分/秒格式的倒计时功能,小数值下运行正常,但设置较大数值(如168800,对应约2天)时,倒计时会逐渐变慢直至停止。

原代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class Timer : MonoBehaviour
{
    [Header("Component")]
    public TextMeshProUGUI timerText;

    [Header("Timer Settings")]
    public float currentTime; 
    public bool countDown;

    [Header("Limit Settings")]
    public bool hasLimit;
    public float timerLimit;

    private bool SetTimerText = false;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        currentTime = countDown ? currentTime -= Time.DeltaTime : currentTime += Time.DeltaTime;

        int seconds = (int)(currentTime % 60);
        int minutes = (int)(currentTime / 60) % 60;
        int hours = (int)(currentTime / 3600) % 24;
        int days = (int)(currentTime / 86400);

        string currentTimeS = string.Format("{0:0} days {1:0} hours {2:00} minutes {3:00} seconds", days,hours,minutes,seconds);

        if((hasLimit) && ((countDown && currentTime <= timerLimit) || (!countDown && currentTime >= timerLimit)))
        {
            currentTime = timerLimit;
            SetTimerText = true;
            timerText.color = Color.red;
            enabled = false;
        }

        SetTimerText = true;

        if(SetTimerText){timerText.text = currentTimeS; SetTimerText = false;}
    }

}

问题原因

核心问题是float类型的精度限制:

  • float是单精度浮点数,仅支持约6-7位有效数字。当currentTime数值很大(比如168800)时,Time.deltaTime(通常在0.016左右)相对于它来说极小,float无法精确表示两者的差值,导致每次减去Time.deltaTime时数值没有变化,最终倒计时停止。
  • 代码中SetTimerText的逻辑存在冗余,多次赋值后失去了原本的控制意义,但这不是导致倒计时停止的主因。

修复方案

把计时相关变量从float换成double(双精度浮点数,支持15-17位有效数字),足以支撑大数值下的精确计时,同时优化冗余逻辑:

修复后的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class Timer : MonoBehaviour
{
    [Header("Component")]
    public TextMeshProUGUI timerText;

    [Header("Timer Settings")]
    // 改用double类型存储时间,提升精度
    public double currentTime; 
    public bool countDown;

    [Header("Limit Settings")]
    public bool hasLimit;
    public double timerLimit;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        // 将Time.deltaTime转换为double参与计算,保证精度
        currentTime = countDown ? currentTime -= (double)Time.deltaTime : currentTime += (double)Time.deltaTime;

        int seconds = (int)(currentTime % 60);
        int minutes = (int)(currentTime / 60) % 60;
        int hours = (int)(currentTime / 3600) % 24;
        int days = (int)(currentTime / 86400);

        string currentTimeS = string.Format("{0:0} days {1:0} hours {2:00} minutes {3:00} seconds", days,hours,minutes,seconds);

        if(hasLimit)
        {
            bool reachedLimit = countDown ? currentTime <= timerLimit : currentTime >= timerLimit;
            if(reachedLimit)
            {
                currentTime = timerLimit;
                timerText.text = currentTimeS;
                timerText.color = Color.red;
                enabled = false;
                return;
            }
        }

        // 直接更新文本,移除冗余的SetTimerText逻辑
        timerText.text = currentTimeS;
    }
}

关键修改点

  1. 将currentTime和timerLimit的类型从float改为double,避免大数值下的精度损失。
  2. 计算时把Time.deltaTime转换为double类型,保证计算过程的精度。
  3. 移除了冗余的SetTimerText变量和逻辑,简化代码流程,直接在Update中更新文本(触发停止条件时提前返回)。

内容的提问来源于stack exchange,提问作者TensiK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 13:43:12