GetWorldDeltaSeconds()

在上一篇文章中,我们控制的坦克移动过慢。在这一篇文章中,我们将指定坦克的移动速度。

如代码清单 1 所示,我们首先添加速度变量。速度默认设置为 2 米每秒,后续可以在编辑器中进一步调整。

代码清单 1 速度变量
  1. UCLASS()
  2. class TOONTANKS_API ATank : public ABasePawn
  3. {
  4.     GENERATED_BODY()
  5.  
  6. private:
  7.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement", meta = (AllowPrivateAccess = "true"))
  8.     float Speed = 200.0f;
  9. };

添加好速度变量之后,我们遇到一个问题:我们需要获取到当前帧与上一帧的时间间隔,但是现在我们并不在 Tick() 函数中。

可以在编辑器中开启帧率显示。虽然帧率稳定,但是实际每帧的执行时间是不一样的。

为了在 Tick 以外的函数里获取当前帧的时间间隔,我们可以使用 UGameplayStatics::GetWorldDeltaSeconds() 函数。它是一个静态函数,好处就是随处可用,其原型为:

  • static double GetWorldDeltaSeconds(const UObject* WorldContextObject);

这边的 WorldContextObject 参数非常灵活,任何合法的 UObject 变量都可以。函数内部会通过传入的 UObject,拿到世界上下文,然后获取到时间间隔。

如果传入的 WorldContextObject 不属于任何世界(例如构造阶段的对象),返回的将是 0。

在运行时逻辑中,只要这个对象是 Actor、Component 或任何游戏对象,可以放心传入它。通常直接传入当前对象的 this 指针。

如代码清单 1 所示,我们使用 GetWorldDeltaSeconds() 获取到时间间隔,然后再作用上速度,以此计算移动距离。

代码清单 1 Move
  1. void ATank::Move(float Value)
  2. {
  3.     // UE_LOG(LogTemp, Warning, TEXT("Value: %f"), Value);
  4.  
  5.     FVector DeltaLocation = FVector::ZeroVector;
  6.     DeltaLocation.X = Value * Speed * UGameplayStatics::GetWorldDeltaSeconds(this);
  7.     AddActorLocalOffset(DeltaLocation);
  8. }

最终的运行效果如下方视频所示,我们把速度调整到 5 米每秒,可以看到坦克的移动比之前快了许多。