서의 공간

Set Timer 사용법 본문

Unreal Engine

Set Timer 사용법

홍서의 2021. 12. 12. 13:39

블루프린트에서 SetTimer

SetTimerbyFunctionName 함수의 파라미터 중 Object 파라미터는 델리게이트 함수를 구현한 오브젝트를 의미하고,
Function Name 파라미터는 델리게이트 함수 이름이다.

C++에서 Set Timer

세 가지 방법이 있다. 먼저 SetTimer를 호출하려면 FTimerManager 인스턴스가 필요하다.

  1. AActor를 상속받은 오브젝트가 아닌 경우 GetWorld()->GetTimerManager() 함수 사용
    예) GetWorld()->GetTimerManager().SetTimer(...);
  2. AActor를 상속받은 오브젝트인 경우 FTimerManager& AActor::GetWorldTimerManager() const 함수 사용
    예) GetWorldTimerManager().SetTimer(...);
  3. KismetSystemLibrary 사용. FTimerHandle UKismetSystemLibrary::K2_SetTimer(UObject* Object, FString FunctionName, float Time, bool bLooping, float InitialStartDelay, float InitialStartDelayVariance) 함수 사용. (KismetSystemLibrary 헤더 파일을 추가해야함)
    예) UKismetSystemLibrary::K2_SetTimer(...);

2, 3번 경우 함수 내부에서 1번에 있는 FTimerManager& UWorld::GetTimerManager() 함수를 호출하여 FTimerManager 인스턴스를 참조, void FTimerManager::SetTimer(...)를 호출한다. SetTimerFTimerManager 클래스의 public 메서드다.
흐름을 정리하자면, 2or3 -> 1 -> SetTimer -> InternalSetTimer -> ... 이다.

제가 set timer에 대해서 잘못 이해했나요? : 네이버 카페 (naver.com)

카페 질문글 참고하여, Tick에서 SetTimer를 하면 어떤 일이 벌어지는지 확인하자.

  1. 첫 Tick에서 Set Timer가 호출되어 Timer Handle이 리턴된다. 1초 후 원하는 델리게이트 함수 또는 이벤트를 호출할 예정이다.
  2. 두 번째 Tick에서 다시 Set Timer가 호출된다. 다음 InternalSetTimer 함수 코드를 살펴보자. 대부분의 코드를 생략했으며, 자세한 내용은 FTimerManager.cpp에서 확인 가능하다.
void FTimerManager::InternalSetTimer(FTimerHandle& InOutHandle, FTimerUnifiedDelegate&& InDelegate, float InRate, bool InbLoop, float InFirstDelay) 
{
    ... 

    // 여기서 timer가 이미 set 되어있다면, 기존 FTimerHandle을 clear 한다. 
    if (FindTimer(InOutHandle)) 
    { 
        // if the timer is already set, just clear it and we'll re-add it, since 
        // there's no data to maintain. 
        InternalClearTimer(InOutHandle); 
    } 

    if (InRate > 0.f) 
    { 
        ... 

        FTimerHandle NewTimerHandle; 
        if (HasBeenTickedThisFrame()) 
        { 
            NewTimerData.ExpireTime = InternalTime + FirstDelay;
            NewTimerData.Status = ETimerStatus::Active;
            NewTimerHandle = AddTimer(MoveTemp(NewTimerData));
            ActiveTimerHeap.HeapPush(NewTimerHandle, FTimerHeapOrder(Timers));
        }
        else 
        { 
            // Store time remaining in ExpireTime while pending 
            NewTimerData.ExpireTime = FirstDelay;
            NewTimerData.Status = ETimerStatus::Pending;
            NewTimerHandle = AddTimer(MoveTemp(NewTimerData));
            PendingTimerSet.Add(NewTimerHandle); 
        } 

        // 앞에서 InOutHandle를 clear 할 수 있기 때문에 로컬 변수로 업데이트 
        InOutHandle = NewTimerHandle; 
    } 
    else
    {
        InOutHandle.Invalidate();
    }
}
  1. 위 코드를 통해, 첫 Tick에서 설정한 타이머가 clear 되고 다시 새로운 타이머를 설정하게 된다. 그럼 다시 현재 Tick으로부터 1초 후 델리게이트 함수 또는 이벤트가 호출될 것이다.
  2. 세 번째 Tick에서 마찬가지로 두 번째 Tick에서 설정한 타이머가 clear되고, 새로운 타이머를 설정한다. 새로운 타이머는 다시 현재 Tick으로부터 1초 후 델리게이트 함수 또는 이벤트가 호출될 것이다.
  3. 이 과정이 Tick마다 반복되어, 결과적으로 게임이 실행되는 동안 델리게이트 함수 또는 이벤트는 호출되지 않는다.

'Unreal Engine' 카테고리의 다른 글

컨트롤러 방향  (2) 2021.12.16
AIController에서 BehaviorTreeComponent  (2) 2021.12.12
속도, MakeFromX, MakeRotFromX  (0) 2021.11.09
Pawn  (0) 2021.11.09
[UMG] Drag & Drop  (0) 2021.10.29
Comments