1. 타이머를 사용하는 액터 만들기

타이머를 사용하여 고정된 속도로 코드를 실행 시작 또는 중지시킵니다.

Windows
MacOS
Linux
On this page

언리얼 엔진 4 에 처음이신 경우, 프로그래밍 퀵스타트 튜토리얼 을 먼저 읽어보세요. 이 튜토리얼은 프로젝트 생성, C++ 코드 추가, 코드 컴파일이 익숙하신 분들을 대상으로 합니다.

  1. 기본 코드 프로젝트에 시작용 콘텐츠를 포함시켜 "HowTo_VTE" 라는 이름으로 만든 다음 액터 클래스를 추가하는 것으로 시작합니다. 이 튜토리얼에서는 이름을 "Countdown" 이라 하겠습니다.

    ChooseParentClass.png

    NameYourActor.png

  2. 게임내에서 볼 수 있는 간단한 카운트 다운 타이머를 만드는 것으로 시작하겠습니다. Countdown.h 에서 클래스 정의 끝에 다음 줄을 추가합니다:

    int32 CountdownTime;
    UTextRenderComponent* CountdownText;
    void UpdateTimerDisplay();
  3. Countdown.cpp 에서, 렌더러블 텍스트 컴포넌트 를 만들어 카운트다운 시간을 3 초로 초기화시키면 됩니다. 이러한 액터 유형에는 Ticking 이 필요치 않으니 꺼도 됩니다. 그러기 위해서는 파일 상단에 컴포넌트에 대한 헤더를 추가해야 하는데, "include" 섹션은 이렇습니다.

    #include "GameFramework/Actor.h"
    #include "Components/TextRenderComponent.h"
    #include "Countdown.generated.h"

    헤더를 포함시켰으니, ACountdown::ACountdown 를 이렇게 작성하면 됩니다.

    ACountdown::ACountdown()
    {
        // 이 액터가 매 프레임 Tick() 을 호출하도록 설정합니다. 필요치 않으면 꺼서 퍼포먼스를 향상시킬 수 있습니다.
        PrimaryActorTick.bCanEverTick = false;
        CountdownText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("CountdownNumber"));
        CountdownText->SetHorizontalAlignment(EHTA_Center);
        CountdownText->SetWorldSize(150.0f);
        RootComponent = CountdownText;
        CountdownTime = 3;
    }
  4. ACountdown::UpdateTimerDisplay 는 남은 시간을 표시하도록 텍스트 디스플레이를 업데이트하거나, 시간이 다 됐으면 0 을 표시합니다. 이 코드는 ACountdown 을 게임에 처음 스폰시킬 때 실행되며, CountdownTime 변수가 0 이 될 때까지 초당 한 번씩 실행됩니다.

    void ACountdown::UpdateTimerDisplay()
    {
        CountdownText->SetText(FString::FromInt(FMath::Max(CountdownTime, 0)));
    }
  5. Timer 에 함수 실행을 할당할 때마다, Timer Handle 이 주어집니다. 카운트다운이 완료되면 Timer 를 종료시킬 수 있도록 그 핸들을 계속 유지해야 합니다. 카운트 다운을 하는 함수와, 그 제어에 필요할 Timer HandleCountdown.h 의 클래스 정의에 추가시킵시다. 거기서 카운트다운이 종료되면 무언가 특별한 작업을 하는 함수도 하나 추가시킵시다:

    void AdvanceTimer();
    
    void CountdownHasFinished();
    
    FTimerHandle CountdownTimerHandle;

    이제 Countdown.cppACountdown::AdvanceTimerACountdown::CountdownHasFinished 본문을 작성할 수도 있습니다:

    void ACountdown::AdvanceTimer()
    {
        --CountdownTime;
        UpdateTimerDisplay();
        if (CountdownTime < 1)
        {
            //카운트 다운이 완료되었으니, 타이머를 중지시킵니다.
            GetWorldTimerManager().ClearTimer(CountdownTimerHandle);
            CountdownHasFinished();
        }
    }
    
    void ACountdown::CountdownHasFinished()
    {
        //특별 문구로 전환합니다.
        CountdownText->SetText(TEXT("GO!"));
    }
  6. 새로운 업데이트 함수로의 호출을 추가하여 ACountdown::BeginPlay 의 텍스트 표시를 초기화시키고, 초당 한 번씩 카운트다운을 진행 및 업데이트하는 타이머 설정을 해 줍시다.

    UpdateTimerDisplay();
    GetWorldTimerManager().SetTimer(CountdownTimerHandle, this, &ACountdown::AdvanceTimer, 1.0f, true);

    ACountdown::ACountdown 이 아닌 ACountdown::BeginPlay 에서 디스플레이를 업데이트하고 있는데, 언리얼 에디터 에서 변수에 설정된 값은 생성자 이후 BeginPlay 이전 할당되기 때문입니다. 나중에 CountdownTime 을 에디터에 노출시킬 때, 그 값을 따라주는 것이 좋을 것입니다.

  7. 언리얼 에디터 로 가서 컴파일 을 눌러 지금까지의 진행상황을 점검해 봅시다.

    CompileFromEditor.png

    그런 다음 콘텐츠 브라우저 에서 ACountdown 클래스를 레벨 에디터 에 떨궈 업데이트할 수 있습니다.

    ClassInContentBrowser.png

    LevelEditorText.png

    카운트다운 텍스트 설정은 ACountdown::ACountdown 가 아닌 ACountdown::BeginPlay 도중 하기 때문에, 기본 "Text" 가 레벨 에디터 에 표시됩니다.

    플레이 를 누르면 카운트다운은 예상대로 "3", "2", "1", 마지막 "GO!" 로 진행됩니다.

이 시점에서 이미 타이머를 사용하는 간단한 클래스가 생성되었습니다. 프로그래머가 아닌 사용자를 위해 카운트다운 시간 설정, 카운트다운 완료시의 작동방식을 변경할 수 있다면 훨씬 활용도가 높을 것입니다. 다음에는 이 기능을 에디터에 노출시키도록 하겠습니다.

작업중 코드

Countdown.h

// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "GameFramework/Actor.h"
#include "Countdown.generated.h"

UCLASS()
class HOWTO_VTE_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 DeltaSeconds ) override;

    //How long, in seconds, the countdown will run
    int32 CountdownTime;

    UTextRenderComponent* CountdownText;

    void UpdateTimerDisplay();

    void AdvanceTimer();

    void CountdownHasFinished();

    FTimerHandle CountdownTimerHandle;
};

Countdown.cpp

// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

#include "HowTo_VTE.h"
#include "Components/TextRenderComponent.h"
#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;

    CountdownText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("CountdownNumber"));
    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)));
}

void ACountdown::AdvanceTimer()
{
    --CountdownTime;
    UpdateTimerDisplay();
    if (CountdownTime < 1)
    {
        // We're done counting down, so stop running the timer.
        GetWorldTimerManager().ClearTimer(CountdownTimerHandle);
        //Perform any special actions we want to do when the timer ends.
        CountdownHasFinished();
    }
}

void ACountdown::CountdownHasFinished()
{
    //Change to a special readout
    CountdownText->SetText(TEXT("GO!"));
}
Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback