游戏卡顿白皮书 › L1 客户端游戏进程
float 时间精度丢失 Float time precision loss on long sessions
原因 ID cg-float-time · 主责 研发团队·客户端开发
在含图示和实验的完整版中打开此卡片 →
用精度较低的小数类型(float)保存游戏时间时,运行越久,时间分辨率(能区分的最小时间差)越低,动作和特效会发生颤动。
起因 把游戏启动后经过的时间累加到 float 里,或直接传给 Shader → 结果 运行越久,float 能表示的最小差值越大 → 画面表现 只有开了几天的客户端,角色、动画、流动特效不停颤动,重启后就正常
- 症状
- 一卡一卡
- 因素
- 抖动
- 谁会遇到
- 只有我
- 何时出现
- 开得越久越严重
- 负责方
- 主责 研发团队·客户端开发
- 研发团队要做的事
- 经过时间用 double(64 位)或整数保存,传给 Shader 的时间定期回绕,做持续好几天的长时间自动化测试。
- 数值参考
- 32 位 float 的有效数字只有 7 位多一点,运行一天(约 86,400 秒)后时间分辨率约为 8 ms,大约是 60 FPS 下一帧(16.7 ms)的一半;一周后约为 60 ms,超过一帧。
- 监控图上
- 缓慢爬升 · 颤动反馈(按客户端运行时长)
- 查看位置
- 收到颤动反馈时一并询问客户端已运行多久,对比重启前后。开发侧可把游戏启动时间设为几天前的值再跑测试
- 确认依据
- 只有开了几天的客户端出现颤动,重启后消失,运行越久越严重
- 排除依据
- 一启动就颤动,看“没有插值缓冲或缓冲过短”或“定时器精度”
- 确认手段
- 需在玩家侧环境确认
- 深入了解
- 在开着自动打怪、好几天都不关的手游 MMO 中尤其常见。Unity 的 Time.time 也是 float,所以 Unity 另外提供了 double 类型的 Time.timeAsDouble,并推荐使用它。
出处
- Time.timeAsDouble Unity
Time.time 的 double 版本;运行越久越比 float 精确,大多数情况推荐用它 - Floating-point numeric types (C# reference) Microsoft
float 精度约 6~9 位,double 约 15~17 位
相关原因
同一层:L1 客户端游戏进程
其他层中同样导致“一卡一卡”的原因
查看含图示和实验的原卡片