ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Unreal Engine] Delay : UKismetSystemLibrary::Delay, SetTimer()
    Unreal Engine 5._ 2023. 1. 24. 17:14

    언리얼의 블루프린트에는 Delay 노드가 존재합니다. (구체적으로는 Delay와 Delay Until Next Tick 입니다.)

    이 노드들은 선택한 시간, 혹은 다음 틱까지 이벤트의 실행을 중지시키는 역할을 합니다.

    지정된 시간동안 실행을 지연시키는 역할을 하는 이 노드는, C++에서는 UKiUKismetSystemLibrary의 메소드로 존재합니다.

    다만, 이를 코드로 확인해보면 블루프린트와는 다른 모습을 볼 수 있습니다.

     

    이번 글에서는 C++에서 블루프린트의 Delay 기능을 사용하는 방법을 살펴보도록 하겠습니다.

     


     

    1. 개요 & FLatentActionInfo

     

    더보기

    C++에 구현된 Delay 관련 함수는 다음과 같습니다.

    UKismetSystemLibrary::Delay
    UKismetSystemLibrary::DelayUntilNextTick
    UKismetSystemLibrary::RetriggerableDelay

    세 함수에 대한 소개를 하기 이전에 세 함수에서 공통적으로 요구되는 매개변수이면서, 블루프린트와는 다른 인자인 FLatentActionInfo 구조체에 대해서 살펴보도록 하겠습니다.

     

    FLatentActionInfo에 대한 자세한 설명은 언리얼 엔진 공식 문서에도 있습니다.

    FLatentActionInfo | Unreal Engine Documentation
    FLatentActionInfo f;
    /* Member of FLatentActionInfo
    f.CallbackTarget // UObject*
    f.ExecutionFunction // FName
    f.Linkage // int32
    f.UUID // int32
    */

    주석은 멤버 변수 각각에 대한 자료형입니다.

    각각의 변수가 의미하는 바는 다음과 같습니다.

    • CallbackTarget
      • 실행할 함수가 있는 객체의 포인터입니다.
    • ExecutionFunction
      • 실행할 함수의 이름입니다.
    • Linkage
      • The resume point within the function to execute
      • 공식 문서의 표현입니다. 하단에 서술하겠습니다.
    • UUID
      • 해당 객체에 대한 UUID입니다.
    실제로 사용하게 될 경우 다음과 같이 사용할 수 있습니다.
    FLatentActionInfo f;
    f.CallbackTarget = this;
    f.ExecutionFunction = FName("Function1");
    f.Linkage = 1;
    f.UUID = 0;
    
    // Usage on delay
    // Delay code

    이 경우, 인스턴스 f는 해당 코드가 실행된 인스턴스(this)의 Function1을 참조하여, 그 함수를 실행시킵니다.

     

    Linkage는 그 함수에 전달되는 인자값의 역할을 할 수 있습니다.

    관련 글이 언리얼 엔진 포럼에 있어 공유합니다.

    How does the FLatentActionInfo Linkage variable work?

     

    다음 문단부터 소개될 Delay 관련 함수들은 위에 소개된 인스턴스 f를 인자로 삼는다고 가정하도록 하겠습니다.

     

    2. UKismetSystemLibrary::Delay

     

    더보기

    Delay함수의 서명에 관한 설명은 언리얼 엔진 공식 문서에 있습니다.

    UKismetSystemLibrary::Delay | Unreal Engine Documentation

     

    사용은 다음과 같이 할 수 있습니다.

    UKismetSystemLibrary::Delay(
        GetWorld(),
        3.0f,
        f
    );

    위와 같이 사용할 경우, 해당 코드가 실행되면 3초 후 f에 지정된 액션(이 글에서는 this 인스턴스의 Function1 함수)이 실행됩니다.

     

    3. UKismetSystemLibrary::RetriggerableDelay

     

    더보기

    RetriggerableDelay함수의 서명에 관한 설명은 언리얼 엔진 공식 문서에 있습니다.

    UKismetSystemLibrary::RetriggerableDelay | Unreal Engine Documentation

     

    사용은 다음과 같이 할 수 있습니다.

    UKismetSystemLibrary::RetriggerableDelay(
        GetWorld(),
        3.0f,
        f
    );

    위와 같이 사용할 경우, 해당 코드가 실행되면 3초 후 f에 지정된 액션(이 글에서는 this 인스턴스의 Function1 함수)이 실행됩니다.

    위 문단의 Delay함수와의 차이점은, 해당 코드를 반복적으로 실행시키는 것으로 실행 타이머를 초기화 시킬 수 있다는 점 입니다.

     

    이 내용을 자세히 살펴볼 수 있는 유튜브 영상을 공유합니다.

    WTF Is? The Delay Nodes

     

    4. UKismetSystemLibrary::DelayUntilNextTick

     

    더보기

    DelayUntilNextTick함수의 서명에 관한 설명은 언리얼 엔진 공식 문서에 있습니다.

    UKismetSystemLibrary::DelayUntilNextTick | Unreal Engine Documentation

     

    사용은 다음과 같이 할 수 있습니다.

    UKismetSystemLibrary::DelayUntilNextTick(
        GetWorld(),
        f
    );

    위와 같이 사용할 경우, 해당 코드가 실행되면 다음 틱에 f에 지정된 액션(이 글에서는 this 인스턴스의 Function1 함수)이 실행됩니다.

    이름 그대로, 시간을 지정하지 않고 다음 틱까지 실행을 지연시키는 함수입니다.

     

    5. Delay의 문제점

     

    더보기

    C++에서 제공하는 Delay함수들의 가장 큰 단점은, 코드의 실행 자체를 지연시키지는 않는 것이라고 생각합니다.

    예를 들어 다음과 같은 코드가 있을 경우

    void AMyActor::BeginPlay() {
        Super::BeginPlay();
        
        // FLatentInfoAction code
        
        UE_LOG(LogTemp, Log, TEXT("Before"));
        UKismetSystemLibrary::Delay(GetWorld(), 3.0f, f);
        UE_LOG(LogTemp, Log, TEXT("After"));
    }

    위 코드에서 기대할 수 있는 결과는 다음이 될 수 있습니다.

    1. 로그에 Begin 출력
    2. 3초 후, f에 지정된 액션이 실행
    3. 로그에 After 출력

    하지만 결과는 다음과 같습니다.

    1. 로그에 Begin 출력
    2. 로그에 After 출력
    3. 3초 후, f에 지정된 액션이 실행

    지연되어 실행해야 하는 함수가 여럿일 경우 이 문제점은 더욱 커집니다.

    여러 함수를 실행시키기 위한 함수를 추가하고, 그 함수를 f에 등록할 수 있지만, 이와 같은 상황이 많아질 경우 코드가 복잡해질 수 있습니다.

     

    다음 문단에서, 이러한 상황에서 Delay의 역할을 할 수 있는 기능을 제시해보려 합니다.

     

    6. SetTimer로 Delay 구현하기

     

    더보기

    SetTimer에 대한 설명은 다른 글에 있습니다.

    [Unreal Engine] SetTimer() : C++ & Blueprint

     

    SetTimer함수 또한 Delay와 마찬가지로 코드를 지연 실행하는 기능을 제공합니다.

    따라서 위 문단에서 제기한 문제점 "여러 함수를 지연시켜서 실행해야 할 때" 를 SetTiemr로 구현할 경우 다음과 같은 코드를 사용할 수 있습니다.

    FTimerHandle handle;
    GetWorld()->GetTimerManager().SetTimer(
        handle,
        FTimerDelegate::CreateLambda([]() {
            /*
            Functions
            */
        }),
        3.0f,
        false
    );

    이 코드는 실행될 때, 3초 후 SetTimer의 두 번째 인자로 전달한 람다식을 실행합니다.

    위와 같은 코드를 통해 여러 함수를 지연시켜서 실행하는 상황에 대응이 가능합니다.

     


     

    Delay함수에 대하여 알아보았습니다.

     

    이 글이 도움이 되셨기를 바랍니다.

    감사합니다.

    댓글

Designed by Tistory.