UE4游戏开发中,许多地方需要使用到时间,UE4时间主要由World管理,而World中又有多种时间,因此在这做一个梳理。
相对时间获取:
World中的时间大部分为相对时间,代表World创建后经过的时间,更准确的说是自World第一次tick开始后经过的时间。
需要注意的是,这些相对时间都用float表示,受浮点数epsilon约束,其最大能精确表示的整型数为16777216,因此长时间不重启的话,可能会出现时间无法递增的问题。
TimeSeconds
World创建后经过的时间,游戏暂停后也会暂停递增,会膨胀/压缩。
“膨胀/压缩”其实就是把tick经过的时间乘以一个系数,达到调整游戏速率的目的。详细可见GetEffectiveTimeDilation()函数,回放时的速率调整就是通过这个系数实现的。但时间膨胀压缩调整是有上限和下限的,通过MinUndilatedFrameTime(默认0.0005,2000fps)和MaxUndilatedFrameTime(默认0.4,2.5fps)控制。设置限制可能是为了处理一些特殊情况,比如断点调试时会一帧卡很久,继续执行时如果直接使用tick间隔,会非常大,一些数值计算上会造成异常,严重点就崩溃了。
UnpausedTimeSeconds
World创建后经过的时间,游戏暂停不会有影响,会膨胀/压缩。
RealTimeSeconds
World创建后经过的真实时间,游戏暂停不会有影响,不会膨胀/压缩。
AudioTimeSeconds
用于声音,World创建后经过的真实时间,游戏暂停后也会暂停递增,不会膨胀/压缩。可能声音调整速率播放会比较奇怪吧。
客户端服务器时间如何统一?
客户端和服务器都有自己的一套相对时间,它们共同做一些与时间相关的操作时必须使用统一的相对时间,不然会错乱。
GameState中有方法可以获取统一时间:
可以看到客户端获取当前服务器时间,做法为本地时间加上一个本地与服务器时间基准差值。
ServerWorldTimeSecondsDelta如何得到呢?在gamestate创建时,服务器会把当前的TimeSeconds同步给客户端,并根据ServerWorldTimeSecondsUpdateFrequency设置进行周期性同步,默认5秒同步一次。客户端收到后就能动态调整自己和服务器的时间差,从而保持时间同步了。
绝对时间获取:
绝对时间可以理解为现实世界中的时间,可以通过FDateTime类获取,可获得的内容包括年、月、日、小时、毫秒等等。最简单的用法为调用Now()方法获取当前时间,底层会去获取当前系统的时间。