[UE C++] Timer timer
1. Key points:
- The UE's Timer includes two functions, delay and timing, which are set through bLoop.
- Timer is managed in FTimerManager , which exists in the UGameInstance instance and can be obtained by each scene item.
- Set Timer to have two
SetTimer
andSetTimerForNextTick
two interfaces - Timer is managed through an FTimerHandle object, including operations such as pausing, resuming, and canceling.
2. FTimerManager
Manage all Timers and exist in the UGameInstance instance. Each scene item can be obtained. The acquisition method is as follows:
GetGameInstance()->GetTimerManager();
GetWorld()->GetTimerManager();
GetWorldTimerManager();
Essentially, it is obtained through UGameInstance::GetTimerManager()
inline FTimerManager& GetTimerManager() const
{
return (OwningGameInstance ? OwningGameInstance->GetTimerManager() : *TimerManager);
}
FTimerManager& AActor::GetWorldTimerManager() const
{
return GetWorld()->GetTimerManager();
}
3. FTimerHandle
Timer handle, used to pause, resume, cancel Timer, and manage Timer
3.1 Statement
FTimerHandle TestTimerHandle;
3.2 Pause and resume
GetWorldTimerManager().PauseTimer(TestTimerHandle);
GetWorldTimerManager().UnPauseTimer(TestTimerHandle);
3.3 Cancel
GetWorldTimerManager().ClearTimer(TestTimerHandle);
//取消指定对象的所有Timer
GetWorldTimerManagerr().ClearAllTimersForObject(this);
3.4 Get Timer status
//Get Rate TimerHandle无效返回-1
GetWorldTimerManager().GetTimerRate(TestTimerHandle);
//是否暂停
GetWorldTimerManager().IsTimerPaused(TestTimerHandle);
//是否活跃且未暂停
GetWorldTimerManager().IsTimerActive(TestTimerHandle);
//是否存在且等待运行
GetWorldTimerManager().IsTimerPending(TestTimerHandle);
//是否存在
GetWorldTimerManager().TimerExists(TestTimerHandle);
//剩余时间 TimerHandle无效返回-1
GetWorldTimerManager().GetTimerRemaining(TestTimerHandle);
//已运行时间 TimerHandle无效返回-1
GetWorldTimerManager().GetTimerElapsed(TestTimerHandle);
4. Set Timer
4.1 SetTimer
There are 6 overloads
//Callback 类的成员函数
void SetTimer
(
FTimerHandle& InOutHandle,
UserClass* InObj,
typename FTimerDelegate::TUObjectMethodDelegate< UserClass >::FMethodPtr InTimerMethod,
//typename FTimerDelegate::TUObjectMethodDelegate_Const< UserClass >::FMethodPtr
float InRate,
bool InbLoop = false,
float InFirstDelay = -1.f
);
//Callback Delegate的Bind函数
void SetTimer
(
FTimerHandle& InOutHandle,
FTimerDelegate const& InDelegate,
//FTimerDynamicDelegate const& InDynDelegate
float InRate,
bool InbLoop,
float InFirstDelay = -1.f
);
DECLARE_DELEGATE(FTimerDelegate);//无法带参数
DECLARE_DYNAMIC_DELEGATE(FTimerDynamicDelegate);//无法带参数
//Callback空气,不知道有啥用
void SetTimer
(
FTimerHandle& InOutHandle,
float InRate,
bool InbLoop,
float InFirstDelay = -1.f
);
//Callback TFunction,常用于Lambda函数(可捕获参数)
void SetTimer
(
FTimerHandle& InOutHandle,
TFunction<void(void)>&& Callback,
float InRate,
bool InbLoop,
float InFirstDelay = -1.f
);
The author believes that the use can be divided into three categories. The following is an example:
first define a test function
void ATimerHandleTest::TimerPrintTest()
{
UE_LOG(LogTemp, Warning, TEXT("Timer Callback"));
}
class member functions
GetWorldTimerManager().SetTimer(TestTimerHandle, this, &ThisClass::TimerPrintTest, 2.0f, true);
Delegate
DECLARE_DELEGATE(FTestTimerHandle);
FTestTimerHandle TestTimerHandleDelegate;
TestTimerHandleDelegate.BindUObject(this, &ThisClass::TimerPrintTest);
GetWorldTimerManager().SetTimer(TestTimerHandle, TestTimerHandleDelegate, 2.0f, true);
TFunction
uses Lambda function as an example here
float t = 10.f;
GetWorldTimerManager().SetTimer(
TestTimerHandle,
[t] {
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, FString::Printf(TEXT("Timer Callback:%f"), t));
},
2.f, true);
Other parameter explanations:
- InRate: loop rate, If <= 0.f, clears existing timers
- InbLoop: Whether to loop
- InFirstDelay: Delay for the first trigger If < 0.f InRate will be used.
4.2 SetTimerForNextTick
Callback will be triggered in the next frame. It is not very commonly used. There are 5 overloads in total, which are basically the same as SetTimer.
FTimerHandle SetTimerForNextTick
(
UserClass* inObj,
typename FTimerDelegate::TUObjectMethodDelegate< UserClass >::FMethodPtr inTimerMethod
//typename FTimerDelegate::TUObjectMethodDelegate_Const< UserClass >::FMethodPtr inTimerMethod
);
FTimerHandle SetTimerForNextTick(FTimerDelegate const& InDelegate);
FTimerHandle SetTimerForNextTick(FTimerDynamicDelegate const& InDynDelegate);
FTimerHandle SetTimerForNextTick(TFunction<void(void)>&& Callback);
I won’t give an example here, it’s basically the same as SetTimer.
5. Precautions
- Timer is not thread-safe and may cause an assertion if accessed from outside the game thread.
- Create a Timer in a class in UE4 inherited from UObject. When the object instance of the class is destroyed, the Timer will also be destroyed.
- It is best not to define a local TimerHandle in a function. Although the Timer will run normally, programmers cannot manually manage the Timer.
- When setting a Timer, if a Timer is already set for this TimerHandle, it will replace the old Timer
- The Timer rate cannot be changed directly, but its TimerHandle call can be used
SetTimer
to clear the Timer and create a new Timer