使用 GetWorld()->GetDeltaSeconds()
可以让游戏逻辑与帧率无关,因为它能够动态调整每一帧的计算结果,使其与帧时间成比例。具体来说,DeltaSeconds
表示当前帧与上一帧之间经过的时间(以秒为单位),使用它可以让游戏逻辑根据每帧的时间变化而调整,从而保证在不同帧率下效果一致。以下是详细解释:
1. 帧率和时间的关系
1.1 帧率的定义
帧率(FPS, Frames Per Second)是指每秒渲染的帧数,代表游戏画面的刷新速度。帧率越高,画面越流畅。通常,帧率波动在 30 到 60 之间,越接近 60 帧,体验越好。
- 高帧率:每秒渲染更多帧,意味着每帧的时间间隔(Delta Time)更短。
- 低帧率:每秒渲染的帧数少,意味着每帧的时间间隔更长。
1.2 帧时间(Delta Time)
帧时间(Delta Time
或 Delta Seconds
)是指每帧之间经过的时间。它可以用公式表示为:
Delta Time=1帧率\text{Delta Time} = \frac{1}{\text{帧率}}Delta Time=帧率1
例如:
- 如果帧率是 60 FPS,
Delta Time
为 160=0.0167\frac{1}{60} = 0.0167601=0.0167 秒。 - 如果帧率是 30 FPS,
Delta Time
为 130=0.0333\frac{1}{30} = 0.0333301=0.0333 秒。
1.3 帧率对游戏逻辑的影响
如果你不使用 Delta Time
,游戏中与时间相关的行为将无法根据帧率自动调整,导致以下问题:
- 高帧率:逻辑执行次数更多,角色移动、动画播放速度更快。
- 低帧率:逻辑执行次数少,角色移动、动画播放速度更慢。
2. 通过 Delta Time
调整游戏逻辑
使用 Delta Time
可以动态调整每帧的变化量,使得最终的变化量与时间成正比。这样可以使游戏逻辑与帧率无关,在高帧率和低帧率下效果一致。
2.1 平滑移动
假设你希望角色每秒移动 200
个单位,如果只使用固定值 200
进行移动,那么在高帧率下,角色将会移动得非常快,而在低帧率下,角色会移动得很慢。
float Speed = 200.0f; // 每秒移动 200 单位 FVector Direction = FVector::ForwardVector; // 没有使用 Delta Time FVector NewLocation = GetActorLocation() + Speed * Direction;
在上述代码中,如果帧率是 60
,角色每帧会移动 200
个单位,1 秒钟移动 200 * 60 = 12000
个单位,这是不对的。
通过使用 Delta Time
,可以保证每秒移动 200
个单位:
void AMyPawn::Tick(float DeltaTime) { Super::Tick(DeltaTime); float Speed = 200.0f; // 每秒移动 200 单位 FVector Direction = FVector::ForwardVector; // 使用 Delta Time 调整移动量 FVector NewLocation = GetActorLocation() + Speed * DeltaTime * Direction; SetActorLocation(NewLocation); }
在该代码中:
- 如果
DeltaTime = 0.0167
(帧率 60),角色每帧移动200 * 0.0167 = 3.34
个单位,1 秒钟移动200
个单位。 - 如果
DeltaTime = 0.0333
(帧率 30),角色每帧移动200 * 0.0333 = 6.66
个单位,1 秒钟仍然移动200
个单位。
2.2 动画播放
如果动画播放是与时间无关的,例如播放一秒内需要的帧数固定,而没有根据 Delta Time
调整帧数,则会出现动画速度随帧率变化的问题。
通过 Delta Time
调整动画时间,保证动画播放速度一致:
void AMyCharacter::PlayAnimation(float DeltaTime) { AnimationTime += DeltaTime; // 使用 Delta Time 更新动画时间 // 根据 AnimationTime 计算动画帧并渲染 }
这样,无论帧率如何波动,动画的播放时间都将保持一致。
2.3 物理计算
物理模拟中,速度、加速度、力等都是与时间相关的变量,如果不使用 Delta Time
,物体的运动将与帧率相关。
例如,更新速度和位置:
void AMyObject::UpdatePhysics(float DeltaTime) { FVector Acceleration = FVector(0, 0, -980); // 重力加速度 Velocity += Acceleration * DeltaTime; // 使用 Delta Time 更新速度 Position += Velocity * DeltaTime; // 使用 Delta Time 更新位置 }
通过 Delta Time
调整速度和位置,可以保证物理模拟在不同帧率下表现一致。
3. 为什么 Delta Time
能保证帧率无关
3.1 时间尺度调整
Delta Time
作为每帧的时间比例因子,通过将逻辑运算乘以 Delta Time
,可以把每帧的运算结果缩放到合理的范围,使得每秒的总变化量与时间成正比。
3.2 保持物理一致性
大多数与物理、动画相关的量(速度、加速度、位置变化)都与时间成正比。通过 Delta Time
可以动态调整这些量,使其在不同的帧率下达到一致效果。
3.3 帧率与时间无关的量
某些量本身是与帧率无关的(例如事件触发、条件判断等),对于这类逻辑不需要使用 Delta Time
,而需要它们触发的后续逻辑(如位置更新、动画播放等)才需要使用 Delta Time
。
4. 避免的问题
- 忘记使用
Delta Time
: 在与时间相关的逻辑中忘记使用Delta Time
,会导致逻辑与帧率相关。 - 错误使用
Delta Time
: 在不需要使用Delta Time
的地方使用它,可能会导致逻辑错误。
5. 总结
Delta Time
是当前帧与上一帧之间的时间间隔,它用于平滑地处理时间相关的游戏逻辑。- 使用
Delta Time
可以让逻辑与帧率无关,使得游戏在不同帧率下表现一致。 - 在处理平滑移动、动画播放、物理模拟等与时间相关的逻辑时,必须使用
Delta Time
进行调整。
补充:在 Unreal Engine 中,UGameplayStatics::GetWorldDeltaSeconds()
其实是一个辅助函数,它用于获取当前世界的 DeltaSeconds
,即帧时间(Delta Time)。它是 GetWorld()->GetDeltaSeconds()
的一种封装,用于在不直接访问 UWorld
指针的情况下,获取当前帧的时间间隔。