Unity 会在每帧中执行一些更新操作。MonoBehaviour 脚本可以通过 MonoBehaviour.Update 方法接入此更新循环。例如,在游戏角色的 Update 方法中,可能会读取游戏手柄的用户输入,然后将角色向前移动一定距离。在处理此类基于时间的动作时,切记游戏的帧率是会变化的,因此 Update 调用之间的时间长度也会有所不同。
游戏的可变帧率通常用每秒帧数即__ FPS__见“第一人称射击游戏”和“每秒帧数”。
See in Glossary 表示。帧率因主机设备的功能以及绘制每帧所需的图形和计算的复杂性等因素而异。例如,当屏幕上有 100 个活动角色时,游戏的运行帧率可能会比只有 1 个角色时更低 。
除非受到质量设置或 Adaptive Performance 包的限制,否则 Unity 会尝试以尽可能快的帧率运行游戏。您可以在执行顺序图的游戏逻辑 (Game Logic) 部分中看到每帧发生的更多详细信息。
设想一个任务,即每次一帧,逐步将物体向前移动。一开始可能会觉得,只需在每一帧将物体平移固定的距离即可:
//C# script example
using UnityEngine;
using System.Collections;
public class ExampleScript : MonoBehaviour {
public float distancePerFrame;
void Update() {
transform.Translate(0, 0, distancePerFrame); // this is incorrect
}
}
但是,使用此代码时,随着帧率的变化,对象的表观速度也会改变。如果游戏以 100 FPS 的速度运行,则对象每秒移动 distancePerFrame 100 次。但是,如果帧率降至 60 FPS(例如,由于 CPU 负载),那么对象每秒就只向前移动 60 次,在相同时间内移动的距离就会更短 。
大多数情况下,尤其是在游戏和动画中,这种情况并不理想。通常更希望游戏中的物体无论帧率如何变化,都能以稳定且可预测的速度移动。解决方案是根据每帧所流逝的时间,来缩放每帧的移动量,可从 Time.deltaTime 属性中读取该时间量:
//C# script example
using UnityEngine;
using System.Collections;
public class ExampleScript : MonoBehaviour {
public float distancePerSecond;
void Update() {
transform.Translate(0, 0, distancePerSecond * Time.deltaTime);
}
}
请注意,移动现在显示为 distancePerSecond 而不是 distancePerFrame。当帧率变化时,移动步长的大小也会相应变化,这样对象的速度就能保持恒定。
根据目标平台,请使用 Application.targetFrameRate 或 QualitySettings.vSyncCount 来设置应用程序的帧率。有关更多信息,请参阅 Application.targetFrameRate API 文档。