Choose your operating system:
Windows
macOS
Linux
언리얼 엔진 4 에 처음이신 경우, 프로그래밍 퀵스타트 튜토리얼
-
기본 코드 프로젝트에 시작용 콘텐츠를 포함시켜 "HowTo_VTE" 라는 이름으로 만든 다음 액터 클래스를 추가하는 것으로 시작합니다. 이 튜토리얼에서는 이름을 "Countdown" 이라 하겠습니다.
-
게임내에서 볼 수 있는 간단한 카운트 다운 타이머를 만드는 것으로 시작하겠습니다.
Countdown.h
에서 클래스 정의 끝에 다음 줄을 추가합니다:int32 CountdownTime; UTextRenderComponent* CountdownText; void UpdateTimerDisplay();
-
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; }
-
ACountdown::UpdateTimerDisplay
는 남은 시간을 표시하도록 텍스트 디스플레이를 업데이트하거나, 시간이 다 됐으면 0 을 표시합니다. 이 코드는ACountdown
을 게임에 처음 스폰시킬 때 실행되며, CountdownTime 변수가 0 이 될 때까지 초당 한 번씩 실행됩니다.void ACountdown::UpdateTimerDisplay() { CountdownText->SetText(FString::FromInt(FMath::Max(CountdownTime, 0))); }
-
Timer
에 함수 실행을 할당할 때마다,Timer Handle
이 주어집니다. 카운트다운이 완료되면Timer
를 종료시킬 수 있도록 그 핸들을 계속 유지해야 합니다. 카운트 다운을 하는 함수와, 그 제어에 필요할Timer Handle
을Countdown.h
의 클래스 정의에 추가시킵시다. 거기서 카운트다운이 종료되면 무언가 특별한 작업을 하는 함수도 하나 추가시킵시다:void AdvanceTimer(); void CountdownHasFinished(); FTimerHandle CountdownTimerHandle;
이제
Countdown.cpp
의ACountdown::AdvanceTimer
와ACountdown::CountdownHasFinished
본문을 작성할 수도 있습니다:void ACountdown::AdvanceTimer() { --CountdownTime; UpdateTimerDisplay(); if (CountdownTime < 1) { //카운트 다운이 완료되었으니, 타이머를 중지시킵니다. GetWorldTimerManager().ClearTimer(CountdownTimerHandle); CountdownHasFinished(); } } void ACountdown::CountdownHasFinished() { //특별 문구로 전환합니다. CountdownText->SetText(TEXT("GO!")); }
-
새로운 업데이트 함수로의 호출을 추가하여
ACountdown::BeginPlay
의 텍스트 표시를 초기화시키고, 초당 한 번씩 카운트다운을 진행 및 업데이트하는 타이머 설정을 해 줍시다.UpdateTimerDisplay(); GetWorldTimerManager().SetTimer(CountdownTimerHandle, this, &ACountdown::AdvanceTimer, 1.0f, true);
ACountdown::ACountdown
이 아닌ACountdown::BeginPlay
에서 디스플레이를 업데이트하고 있는데, 언리얼 에디터 에서 변수에 설정된 값은 생성자 이후 BeginPlay 이전 할당되기 때문입니다. 나중에CountdownTime
-
언리얼 에디터 로 가서 컴파일 을 눌러 지금까지의 진행상황을 점검해 봅시다.
그런 다음 콘텐츠 브라우저 에서
ACountdown
클래스를 레벨 에디터 에 떨궈 업데이트할 수 있습니다.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!"));
}