🎯 目标
✅ 理解 UE5 中定时器(Timer)的原理与用途
✅ 使用 FTimerHandle 实现事件延时、倒计时系统
✅ 比较 Tick() 与 Timer 的使用场景
✅ 构建一个简单的倒计时示例
1️⃣ 为什么需要时间管理?
在游戏开发中,很多行为不需要每帧都更新,而是按照一定时间间隔执行,例如:
- 延迟执行事件(如开火冷却、动画播放完成后触发后续逻辑)
- 倒计时效果(如倒计时计时器)
- 优化性能:与 Tick() 相比,定时器能减少不必要的每帧计算
UE5 提供了 FTimerHandle 和 UGameplayStatics::GetWorldTimerManager() 来管理定时器,使开发者可以方便地安排事件执行时间。
2️⃣ Tick() vs Timer
- Tick() 函数:每帧调用,适合需要持续更新的逻辑,但可能会带来性能损耗。
- Timer(定时器):按照指定的时间间隔调用函数,非常适合执行延时任务或周期性任务,且不需要每帧更新,从而提高性能。
3️⃣ 使用 FTimerHandle 实现定时任务
我们可以使用定时器来延迟执行某个函数。下面是一个简单的例子:
代码示例:延时执行函数
// MyCharacter.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MyCharacter.generated.h"
UCLASS()
class MYGAME_API AMyCharacter : public ACharacter
{
GENERATED_BODY()
public:
AMyCharacter();
protected:
virtual void BeginPlay() override;
// 延时执行函数
UFUNCTION()
void DelayedFunction();
private:
// 定时器句柄
FTimerHandle TimerHandle_DelayedFunction;
};
// MyCharacter.cpp
#include "MyCharacter.h"
#include "Kismet/GameplayStatics.h"
AMyCharacter::AMyCharacter()
{
PrimaryActorTick.bCanEverTick = true;
}
void AMyCharacter::BeginPlay()
{
Super::BeginPlay();
// 延迟 3 秒后执行 DelayedFunction
GetWorldTimerManager().SetTimer(TimerHandle_DelayedFunction, this, &AMyCharacter::DelayedFunction, 3.0f, false);
}
void AMyCharacter::DelayedFunction()
{
UE_LOG(LogTemp, Warning, TEXT("延时函数被调用!"));
}
✅ 说明: 上述代码将在游戏开始 3 秒后输出日志,演示了如何使用 FTimerHandle 延时调用函数。
4️⃣ 实现倒计时系统
通过定时器可以实现一个简单的倒计时系统,用于显示剩余时间或触发游戏事件。
代码示例:倒计时系统
// MyCharacter.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MyCharacter.generated.h"
UCLASS()
class MYGAME_API AMyCharacter : public ACharacter
{
GENERATED_BODY()
public:
AMyCharacter();
protected:
virtual void BeginPlay() override;
// 倒计时更新函数
UFUNCTION()
void UpdateCountdown();
// 当前倒计时秒数
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Timer")
int32 CountdownTime;
private:
FTimerHandle TimerHandle_Countdown;
};
// MyCharacter.cpp
#include "MyCharacter.h"
#include "TimerManager.h"
AMyCharacter::AMyCharacter()
{
PrimaryActorTick.bCanEverTick = true;
CountdownTime = 10; // 倒计时 10 秒
}
void AMyCharacter::BeginPlay()
{
Super::BeginPlay();
// 每秒调用一次 UpdateCountdown
GetWorldTimerManager().SetTimer(TimerHandle_Countdown, this, &AMyCharacter::UpdateCountdown, 1.0f, true);
}
void AMyCharacter::UpdateCountdown()
{
CountdownTime--;
UE_LOG(LogTemp, Warning, TEXT("倒计时:%d 秒"), CountdownTime);
if (CountdownTime <= 0)
{
// 倒计时结束,清除定时器
GetWorldTimerManager().ClearTimer(TimerHandle_Countdown);
UE_LOG(LogTemp, Warning, TEXT("倒计时结束!"));
}
}
✅ 说明: 每秒更新一次倒计时,倒计时结束后清除定时器并输出结束信息。
5️⃣ 总结
✅ 定时器提供了一种高效的方式来延迟执行和周期性执行任务
✅ 与 Tick() 相比,使用 Timer 可降低性能消耗
✅ 通过 FTimerHandle,我们可以方便地实现延时函数调用和倒计时系统
✅ 以上示例展示了延时执行和倒计时系统的基本实现方法
🎮 现在,你已经掌握了 UE5 中时间管理的核心知识,能为游戏中的事件调度和倒计时等功能打下坚实基础!🚀