Choose your operating system:
Windows
macOS
Linux
블루프린트 를 사용하여 C++ 클래스의 함수성을 확장시킵니다. 하지만 이는 C++ 코드가 제대로 작성되었나 테스트하기 위한 용도이지, 블루프린트 튜토리얼은 아닙니다. 블루프린트 에 대한 제대로 된 소개는, 블루프린트 퀵스타트 가이드
-
ACountdown 인스턴스 중 "Countdown1" 이라는 녀석의 작동방식을 에디터에서 변경하기 위해, 먼저 그 편집가능 블루프린트 버전을 만들어야 합니다. 그러기 위해서는, 월드 아웃라이너 에서 선택한 다음 디테일 패널 의 블루프린트/스크립트 추가 버튼을 누릅니다.
거기서, 우리 변경된 ACountdown 클래스가 저장될 블루프린트 애셋의 경로와 이름을 제공해 주면 됩니다.
그러면 "Countdown1" 의 블루프린트 버전을 나타내는 애셋이 새로 생깁니다. "Countdown1" 을 새로 만든 블루프린트 인스턴스로 대체되기도 하므로, 블루프린트 에 가한 변경사항이 게임에서 "Countdown1" 에 영향을 끼칩니다.
-
언리얼 에디터 는 자동으로 콘텐츠 브라우저 에서 새 애셋 위치로 이동되며, 거기에 우클릭한 다음 "편집..." 을 선택하여 블루프린트 그래프 , 컴포넌트 계층구조, 기본값 을 변경합니다.
-
함수와 이벤트는 이벤트 그래프 탭에서 찾을 수 있으며, 먼저 선택하겠습니다.
그런 다음 이벤트 그래프 창 아무데나 우클릭한 다음 우리 CountdownHasFinished 함수를 이벤트 노드로 추가하여 그 작동방식을 정의합니다.
-
이제 새로운 노드 오른편의 하양 ("실행") 핀을 좌클릭으로 끌어 놓는 것으로 함수성을 원하는 만큼 추가시킬 수 있습니다.
왼쪽 마우스 버튼을 놓을 때, 어떤 함수나 이벤트를 실행하겠느냐고 묻습니다. 이 튜토리얼에서는 카운트 다운이 완료되면 파티클 시스템 을 스폰하겠습니다. Spawn Emitter At Location 노드가 필요하니, 목록에서 선택해 줍니다. 검색창에 "spawn loc" 정도 텍스트를 부분 입력하면 시간이 절약될 수 있습니다. 그런 다음 노랑 "Location" 핀을 좌클릭으로 끌어 Get Actor Location 함수에 연결합니다.
이제 보고픈 이펙트를 선택해 주면 됩니다. 이미터 템플릿 아래 애셋 선택 을 클릭하여 적합한 이펙트 애셋 목록을 구할 수 있습니다. "P_Explosion" 이 괜찮으니 선택해 주겠습니다.
-
블루프린트 에디터 좌상단의 컴파일 버튼을 클릭하여 변경사항을 저장합니다.
-
이제 플레이 를 누르면 카운트다운이 있은 후 0 에 도달하면 폭발이 생기는 것을 볼 수 있습니다.
그런데 카운트다운이 "0" 이 아닌 "GO!" 라고 하도록 프로그래밍을 해 놨었습니다. C++ 함수성을 블루프린트 비주얼 스크립트로 완전히 대체했기에 더이상 벌어지지 않습니다. 이 경우는 의도했던 바가 아닌데, 이 함수의 C++ 버전 호출을 추가해 주겠습니다. Countdown Has Finished 노드를 우클릭하고 컨텍스트 메뉴에서 "Add call to parent function" 를 선택해 주면 됩니다.
이렇게 하면 이벤트 그래프 에 **Parent: ProgrammingAndScripting/ProgrammingWithCPP/CPPTutorials/VariablesTimersEvents
이렇게 하면 Spawn Emitter At Location 로의 접속이 대체되므로, **Parent: ProgrammingAndScripting/ProgrammingWithCPP/CPPTutorials/VariablesTimersEvents
이제 게임 실행하고, 카운트다운이 끝나면 (C++ 코드의) "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
UPROPERTY(EditAnywhere)
int32 CountdownTime;
UTextRenderComponent* CountdownText;
void UpdateTimerDisplay();
void AdvanceTimer();
UFUNCTION(BlueprintNativeEvent)
void CountdownHasFinished();
virtual void CountdownHasFinished_Implementation();
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_Implementation()
{
//Change to a special readout
CountdownText->SetText(TEXT("GO!"));
}