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

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

Windows
MacOS
Linux

언리얼 엔진 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

새로운 언리얼 엔진 4 문서 사이트에 오신 것을 환영합니다!

문서 사이트에 대한 의견을 모을 수 있는 피드백 시스템을 포함해서 여러가지 새로운 기능을 준비하고 있습니다. 아래 Documentation Feedback 포럼(영문) 또는 언리얼 엔진 네이버 공식 카페(한글) 중 편하신 곳에 의견이나 문제점을 알려 주세요.

새 시스템이 준비되면 알려 드리겠습니다.

네이버 카페
공식 포럼