第 19 天:时间管理(Timers),让事件按时间执行!

🎯 目标

理解 UE5 中定时器(Timer)的原理与用途
使用 FTimerHandle 实现事件延时、倒计时系统
比较 Tick() 与 Timer 的使用场景
构建一个简单的倒计时示例


1️⃣ 为什么需要时间管理?

在游戏开发中,很多行为不需要每帧都更新,而是按照一定时间间隔执行,例如:

  • 延迟执行事件(如开火冷却、动画播放完成后触发后续逻辑)
  • 倒计时效果(如倒计时计时器)
  • 优化性能:与 Tick() 相比,定时器能减少不必要的每帧计算

UE5 提供了 FTimerHandleUGameplayStatics::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 中时间管理的核心知识,能为游戏中的事件调度和倒计时等功能打下坚实基础!🚀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bluesonli

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值