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

Unity中如何实现每秒数百/数千次的稳定时间递减计算?

问题根源

你当前写法出现长时长计时偏差的核心原因是对WaitForSeconds的精度有错误假设:

  • Unity协程的WaitForSeconds调度受帧率、引擎主线程负载影响,单次实际等待时长几乎不可能刚好等于你传入的0.01f,帧率低、主线程卡顿的时候单次等待可能达到几十毫秒
  • 你固定每次循环给subtractTime减1的逻辑,默认每次等待刚好是10ms,累计误差会随着时长增加不断放大,6秒场景下误差会累积到几百毫秒甚至秒级,感知非常明显
  • 逐次递减的逻辑本身就没有精度可言,哪怕把等待间隔压到更小,也解决不了累计误差问题,反而会增加不必要的性能开销
优化方案

彻底放弃固定步长逐次减1的计时逻辑,改用时间差直接计算剩余值的方案,计时精度完全不依赖协程等待频率,哪怕每秒只刷新10次也不会有误差:

  1. 项目激活时,先记录启动时间戳和配置好的项目总时长
  2. 每次循环直接用当前时间减去启动时间,算出已经流逝的时长,直接推导剩余的subtractTime值
  3. 剩余值归零时标记完成,退出循环即可

代码实现

版本1:受游戏时间缩放影响(游戏暂停时计时同步暂停)

适合和游戏进程绑定、不需要计算离线收益的普通计时场景:

// 初始化时把原来乘100的时长转成秒单位,处理等级带来的时长减半逻辑
float totalDuration = subtractTime / 100f;
// 满足等级条件直接减半时长
if (currentProjectLevel >= targetReduceLevel)
{
    totalDuration /= 2f;
}
float startGameTime = Time.time;
completed = false;

while (true)
{
    // 直接计算已流逝时长,推导剩余值,不需要逐次减1
    float elapsedTime = Time.time - startGameTime;
    subtractTime = Mathf.Max(0, (int)((totalDuration - elapsedTime) * 100));
    
    if (subtractTime <= 0)
    {
        break;
    }
    // 等待频率根据UI刷新需求设置即可,哪怕yield return null每帧执行也不会有额外精度问题
    // 不需要刻意追求每秒上千次执行,60帧每秒的刷新频率人眼完全感知不到卡顿
    yield return null;
}
completed = true;

版本2:真实时间计时(不受帧率、暂停影响,支持离线收益计算)

适合放置类游戏的核心计时逻辑,切后台、游戏暂停都不会影响计时准确性:

float totalDuration = subtractTime / 100f;
if (currentProjectLevel >= targetReduceLevel)
{
    totalDuration /= 2f;
}
// 记录UTC时间戳,避免玩家修改本地时间带来的计时异常
DateTime startTime = DateTime.UtcNow;
completed = false;

while (true)
{
    TimeSpan elapsedRealTime = DateTime.UtcNow - startTime;
    subtractTime = Mathf.Max(0, (int)((totalDuration - (float)elapsedRealTime.TotalSeconds) * 100));
    
    if (subtractTime <= 0)
    {
        break;
    }
    // 按需设置刷新间隔,0.01f~0.05f都可以,完全不影响计时精度
    yield return new WaitForSeconds(0.02f);
}
completed = true;
额外说明
  • 不需要追求每秒数百/数千次的递减频率,计时精度和循环执行次数没有关系,只要最终时间计算准确即可,过高的刷新频率只会带来无意义的性能开销
  • 防重复激活的逻辑直接在激活入口判断completed状态或者subtractTime > 0即可,不需要额外加互斥逻辑
  • 如果要做离线收益,只需要在游戏启动时读取上次退出的时间戳,直接计算离线期间完成的项目和收益即可,不需要保持协程持续后台运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:36:16