UE4 Version: 4.27.0 Visual Studio 2019 16.10.2
在UE4使用计时器实现一个倒计时事件
.h文件定义
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/TextRenderComponent.h"
#include "Countdown.generated.h"
UCLASS()
class CLASSSIMPES_API ACountdown : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ACountdown();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere)
int32 CountdownTime;
UTextRenderComponent* CountdownText;
void UpdateTimerDisplay();//更新显示
void AdvanceTimer();
void CountdownHasFinished();//时间结束时的特殊动作
FTimerHandle CountdownTimerHandle;//句柄
};
类定义详解
int32 CountdownTime//定义了一个int32类型的倒计时时间
- int32为虚幻整数类型,虚幻整数类型分为有符号和无符号,分别为
int
和unit
,有8,16,32,64四种。
UTextRenderComponent* CountdownText//定义了一个UTextRenderComponent类的可显示文本组件
- 在头文件中只是先声明,在cpp里还要用CreateDefaultSuobject创建完整的组件
void UpdateTimerDisplay()//创建了一个更新器,用于更新显示字体
void AdvanceTimer()//
void CountdownHasFinished()//用于结束时执行的特殊动作
FTimerHandle CountdownTimerHandle//定义了一个句柄
- 句柄:用于识别的唯一ID
.cpp文件
#include "Countdown.h"
// Sets default values
ACountdown::ACountdown()//类当中的参数初始化
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
//将此Actor设为逐帧调用Tick(),关闭提高性能
CountdownText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("CountdownNumber"));//添加TEXTRENDER组件
CountdownText->SetHorizontalAlignment(EHTA_Center);//设置对齐方式
CountdownText->SetWorldSize(150.0f);//设置大小
RootComponent = CountdownText;//设置这个组件为根组件
CountdownTime = 3;//初始化倒计时
}
// Called when the game starts or when spawned
void ACountdown::BeginPlay()//开始时执行
{
Super::BeginPlay();
UpdateTimerDisplay();//
GetWorldTimerManager().SetTimer(CountdownTimerHandle, this, &ACountdown::AdvanceTimer, 1.0f, true);
}
// Called every frame
void ACountdown::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ACountdown::UpdateTimerDisplay()
{
CountdownText->SetText(FString::FromInt(FMath::Max(CountdownTime, 0)));
//Max:比较两数较大者,并返回较大数
//FromInt:强制类型转换,将int类型强制转化为string类型
//settext:设置字体组件里的值
}
void ACountdown::AdvanceTimer()
{
--CountdownTime;//减去倒数时间1
UpdateTimerDisplay();//更新显示
if (CountdownTime < 1)
{
//倒数完成,停止运行定时器
GetWorldTimerManager().ClearTimer(CountdownTimerHandle);
CountdownHasFinished();
}
}
void ACountdown::CountdownHasFinished()
{
//改为特殊读出
CountdownText->SetText(TEXT("GO"));
}
.cpp文件详解
Countdown()构造函数
CreateDefaultSubobject
初始化SetHorizontalAlignment(EHTA_Center);
设置对齐方式:对齐方式还有EHTA_Left,EHTA_Right.SetWorldSize(150.0f);
设置大小,接受一个浮点值CountTime
初始化倒计时时间
UpdateTimerDisplay()
SetText(FString::FromInt(FMath::Max(CountdownTime, 0)))
- //Max:比较两数较大者,并返回较大数
- //FromInt:强制类型转换,将int类型强制转化为string类型
- //settext:设置字体组件里的值
AdvanceTimer()//计时器,实行倒计时事件
定时器函数(Timer)
template<class UserClass>
void SetTimer
(
FTimerHandle & InOutHandle,
UserClass * InObj,
typename FTimerDelegate::TUObjectMethodDelegate< UserClass >::FMethodPtr InTimerMethod,
float InRate,
bool InbLoop,
float InFirstDelay
)
- InOutHandle 是我们要设置的计时器,即句柄
- UserClass 调用timer函数的object(
this
) - InTimerMethod timer会重复执行的方法(
&ACountdown::AdvanceTimer
) - InRate 调用频率,例如填0.5f的话,那么InTimerMethod就会每隔0.5f调用一次
- InbLoop 是否循环,如果是false的那么方法只会执行一次
- InFirstDelay 第一次调用之前延时的时间,例如5.0f,那么过5秒后,方法才执行,然后才根据InRate 正常调用。