Unity的Time类
Unity Time 类详解及使用场景举例
Unity 的 Time 类是处理时间相关逻辑的核心工具类,提供了与游戏运行时间、帧率、时间缩放相关的关键属性和方法,几乎所有需要“随时间变化”的逻辑(如移动、动画、冷却、计时)都依赖它。其核心价值是屏蔽硬件性能差异,让逻辑在不同帧率设备上表现一致,同时支持时间暂停、慢动作等特殊效果。
一、Time 类核心属性分类
按功能可分为 4 大类:基础时间属性(绝对/相对时间)、帧率相关属性、时间缩放相关属性、deltaTime 系列(帧时间核心),以下逐一详解并附使用场景。
二、核心属性详解 + 实用场景举例
1. 基础时间属性(记录游戏/系统绝对时间)
这类属性不受帧率、Time.timeScale 影响,用于记录“真实流逝时间”或“游戏运行总时长”。
| 属性名 | 官方定义 | 通俗解释 | 使用场景 | 代码示例 |
|---|---|---|---|---|
Time.time |
游戏启动到当前帧的总时间(秒),受 timeScale 影响 |
游戏内“相对时间”,暂停时(timeScale=0)会停止增长 |
记录游戏单局时长、技能持续时间(非实时冷却) | 例:统计玩家存活时间float survivalTime = Time.time - startTime;(startTime 是游戏开始时记录的 Time.time) |
Time.realtimeSinceStartup |
游戏启动到当前的真实时间(秒),不受 timeScale 和暂停影响 |
系统级“绝对时间”,哪怕游戏暂停/后台运行也会增长 | 实时冷却(如后台倒计时)、防作弊计时、性能监控 | 例:后台倒计时(切换应用仍继续)float coolDown = 10f;float lastUseTime = Time.realtimeSinceStartup;if (Time.realtimeSinceStartup - lastUseTime >= coolDown) { 允许使用技能; } |
Time.unscaledTime |
游戏启动到当前帧的总时间(秒),不受 timeScale 影响 |
游戏内“绝对时间”,暂停时仍会增长(区别于 realtimeSinceStartup:不包含游戏后台时间) | 暂停时仍需运行的逻辑(如暂停菜单倒计时、UI 动画) | 例:暂停时显示“3秒后继续”float pauseEndTime = Time.unscaledTime + 3f;void Update() {if (isPaused) {float remain = pauseEndTime - Time.unscaledTime;if (remain <= 0) 取消暂停;}} |
Time.fixedTime |
固定更新(FixedUpdate)的累计时间,受 timeScale 影响 |
专门用于物理/固定步逻辑的“时间轴” | 物理相关的计时(如刚体运动时长、固定步冷却) | 例:每 2 秒触发一次物理检测float fixedInterval = 2f;if (Time.fixedTime - lastFixedCheckTime >= fixedInterval) {Physics.OverlapSphere(transform.position, 5f);lastFixedCheckTime = Time.fixedTime;} |
Time.unscaledFixedTime |
固定更新的累计时间,不受 timeScale 影响 |
固定步逻辑中的“绝对时间” | 暂停时仍需执行的固定步逻辑(如暂停时的物理碰撞检测) | 例:暂停时检测玩家是否点击物体(用物理射线)void FixedUpdate() {if (isPaused && Time.unscaledFixedTime - lastCheckTime >= 0.1f) {Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);lastCheckTime = Time.unscaledFixedTime;}} |
2. deltaTime 系列(帧时间核心,最常用)
deltaTime 表示“上一帧到当前帧的时间间隔(秒)”,是实现帧率无关逻辑的关键——无论设备帧率是 30fps 还是 60fps,相同逻辑的移动速度、动画进度都会一致。
| 属性名 | 核心特点 | 适用场景 | 代码示例 |
|---|---|---|---|
Time.deltaTime |
受 timeScale 影响(暂停时为 0) |
游戏核心逻辑(移动、旋转、普通动画、随时间增长的数值) | 例1:物体匀速移动(帧率无关)float speed = 5f; // 每秒移动5米transform.Translate(Vector3.forward * speed * Time.deltaTime);例2:数值随时间增长(如能量恢复) float energyRecoveryRate = 10f; // 每秒恢复10点能量energy += energyRecoveryRate * Time.deltaTime; |
Time.unscaledDeltaTime |
不受 timeScale 影响(暂停时仍有值) |
暂停时需继续的逻辑(UI 动画、暂停菜单滚动、实时倒计时) | 例:暂停时 UI 面板淡入CanvasGroup alphaGroup;float fadeSpeed = 2f;void Update() {if (isPaused) {alphaGroup.alpha += fadeSpeed * Time.unscaledDeltaTime;alphaGroup.alpha = Mathf.Clamp01(alphaGroup.alpha);}} |
Time.fixedDeltaTime |
固定时间间隔(默认 0.02 秒 = 50 帧/秒),用于 FixedUpdate |
物理逻辑(刚体受力、碰撞检测)、需要固定步长的逻辑 | 例:给刚体施加持续力(物理移动)Rigidbody rb;float force = 10f;void FixedUpdate() {rb.AddForce(Vector3.forward * force * Time.fixedDeltaTime);} |
⚠️ 关键注意:
Update()中必须用Time.deltaTime,FixedUpdate()中必须用Time.fixedDeltaTime(或直接省略,因 FixedUpdate 间隔固定,但建议显式写以统一逻辑);- 绝对不要在
FixedUpdate()中用Time.deltaTime(会导致逻辑速度异常,因 FixedUpdate 间隔与渲染帧无关)。
3. 帧率相关属性(监控性能/适配帧率)
用于获取游戏当前帧率或限制帧率,主要用于性能监控、调试或适配低性能设备。
| 属性名 | 官方定义 | 通俗解释 | 使用场景 | 代码示例 |
|---|---|---|---|---|
Time.frameCount |
游戏启动到当前的总帧数 | 统计帧数、按帧数触发逻辑 | 例:每 60 帧打印一次日志(调试用)if (Time.frameCount % 60 == 0) {Debug.Log("当前帧率:" + Time.deltaTime);} |
|
Time.fps |
当前帧率(每秒帧数),Unity 2020+ 新增(旧版本需自行计算) | 性能监控、显示帧率UI | 例:在屏幕上显示当前帧率Text fpsText;void Update() {fpsText.text = "FPS: " + Mathf.RoundToInt(Time.fps);} |
|
Time.maximumDeltaTime |
限制 deltaTime 的最大值(默认 0.333 秒 = 3fps) |
防止低性能设备帧间隔过大导致逻辑“跳变”(如快速移动穿过物体) | 例:适配低端机,限制最小帧率为 2fpsTime.maximumDeltaTime = 0.5f; // 帧间隔最大0.5秒 |
|
Time.captureFramerate |
强制游戏以指定帧率运行(用于录制视频) | 游戏录屏、制作慢动作视频 | 例:以 15fps 录制视频void StartRecord() {Time.captureFramerate = 15;} |
⚠️ 旧版本(Unity 2020 前)无 Time.fps,需自行计算:
float fps;
float updateInterval = 1f; // 每1秒更新一次帧率
float accum = 0f;
int frameCount = 0;
void Update() {
accum += Time.deltaTime;
frameCount++;
if (accum >= updateInterval) {
fps = frameCount / accum;
accum = 0f;
frameCount = 0;
Debug.Log("FPS: " + Mathf.RoundToInt(fps));
}
}
4. 时间缩放相关属性(控制时间流速)
Time.timeScale 是“时间缩放因子”,用于控制游戏时间的流逝速度,是实现暂停、慢动作、快进的核心。
| 属性名 | 核心作用 | 取值范围 & 效果 | 使用场景 | 代码示例 |
|---|---|---|---|---|
Time.timeScale |
控制游戏时间流速(影响 time、deltaTime、fixedDeltaTime) |
- 0:暂停(所有受时间影响的逻辑停止) - 0~1:慢动作(如 0.5 = 半速) - 1:正常速度 - >1:快进(如 2 = 2倍速) |
暂停功能、慢动作特效(如击杀后慢放)、快进(如跳过剧情) | 例1:游戏暂停/恢复public void PauseGame() { Time.timeScale = 0; }public void ResumeGame() { Time.timeScale = 1; }例2:击杀后慢动作 1 秒 IEnumerator SlowMotionAfterKill() {Time.timeScale = 0.2f; // 20% 速度yield return new WaitForSecondsRealtime(1f); // 用实时时间等待,避免受timeScale影响Time.timeScale = 1f; // 恢复正常} |
Time.timeScaleIndependentSleepTimeout |
控制设备是否在 timeScale=0 时休眠 |
true:暂停时设备不休眠;false:暂停时设备正常休眠 | 避免暂停后设备自动锁屏(如暂停菜单停留时) | Time.timeScaleIndependentSleepTimeout = true; |
⚠️ 关键注意:
timeScale=0时,Time.deltaTime会变成 0,但Time.realtimeSinceStartup、Time.unscaledDeltaTime仍正常工作;- 用
WaitForSeconds()时,等待时间会受timeScale影响(如timeScale=0.5时,WaitForSeconds(2)实际等待 4 秒);若需不受影响的等待,用WaitForSecondsRealtime()。
三、常用方法
| 方法名 | 作用 | 使用场景 |
|---|---|---|
Time.fixedUnscaledDeltaTime |
固定更新的“非缩放帧时间”(不受 timeScale 影响) |
暂停时仍需执行的固定步逻辑(如物理检测) |
Time.SetTimeout(int timeout) |
设置设备自动休眠时间(秒),0 表示永不休眠 | 长时间游戏(如挂机类)避免设备休眠 |
Time.realtimeSinceStartupAsDouble |
高精度版本的 realtimeSinceStartup(double 类型) |
需精确计时的场景(如服务器同步、防作弊) |
四、避坑指南(关键注意事项)
-
deltaTime 的使用场景绝对不能错:
Update()→Time.deltaTime(游戏逻辑);FixedUpdate()→Time.fixedDeltaTime(物理逻辑);- 暂停时 →
Time.unscaledDeltaTime(UI/实时逻辑)。
-
timeScale 与等待方法的配合:
- 受
timeScale影响:WaitForSeconds()、Invoke(); - 不受影响:
WaitForSecondsRealtime()、InvokeRepeating()(需注意间隔是否受影响)。
- 受
-
避免用帧率直接计算时间:
- 错误做法:
float speed = 5f; transform.Translate(Vector3.forward * speed / 60);(假设 60fps,低帧率时会变慢); - 正确做法:
transform.Translate(Vector3.forward * speed * Time.deltaTime);(帧率无关)。
- 错误做法:
-
固定时间步长的调整:
Time.fixedDeltaTime可在 Editor 中设置(Edit → Project Settings → Time → Fixed Timestep),或代码动态修改;- 物理逻辑异常(如刚体穿模)时,可减小
fixedDeltaTime(如 0.01 秒 = 100 帧/秒),但会增加性能消耗。
五、总结
Unity 的 Time 类是游戏时间管理的“中枢”,核心用法可归纳为 3 点:
- 用
deltaTime系列实现帧率无关逻辑(移动、数值增长); - 用
timeScale控制时间流速(暂停、慢动作); - 用
realtimeSinceStartup/unscaledTime处理不受时间缩放影响的实时逻辑(冷却、UI 动画)。