이번 포스트에서는 사용자에게 데이터를 보여주고 사용자로부터 데이터를 입력받는 UI를 만들겠습니다.
프로젝트에서 UI는 MVC 패턴을 사용하여 만들겠습니다.
MVC 패턴은 Model, View, Controller의 3가지로 구성됩니다.
각각 수행하는 역할에 차이가 있습니다.
Model은 데이터를 다루는 쪽을 의미합니다. 프로젝트에서는 Attribute Set을 의미합니다.
View는 보여지는 쪽을 의미합니다. 프로젝트에서는 UI를 의미합니다.
Controller는 Model의 정보를 View로 전달하거나 View의 정보를 Model에 전달합니다.
따라서 이를 위해 View와 Controller 역할을 수행하는 클래스를 만들겠습니다.
언리얼에서 UI 역할을 하는 Widget들은 UUserWidger 클래스에서 상속되므로 UUserWidget으로 만들고,
Controller의 경우 UObject로부터 상속하여 만들겠습니다.
최종적으로 UI를 구성하기 위해서는 다음의 3가지 클래스를 만들예정입니다.
UI에서 개별 UI를 담당하는 클래스인 UUserWidget,
Model과 View 사이에서 움직이는 클래스인 UWidgetController
마지막으로 UI를 전부 모아놓은 AHUD를 만들겠습니다.
1) Controller 역할을 수행하는 AAuraWidgetController
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "AuraWidgetController.generated.h"
class APlayerController;
class APlayerState;
class UAbilitySystemComponent;
class UAttributeSet;
/**
*
*/
UCLASS()
class AURA_API UAuraWidgetController : public UObject
{
GENERATED_BODY()
protected:
// UI 입력시에 입력을 Model(=데이터)로 전달
UPROPERTY(BlueprintReadOnly, Category = "WidgetController")
TObjectPtr<APlayerController> PlayerController;
// Model(=데이터)를 View(=UI)로 전달
UPROPERTY(BlueprintReadOnly, Category = "WidgetController")
TObjectPtr<APlayerState> PlayerState;
UPROPERTY(BlueprintReadOnly, Category = "WidgetController")
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
UPROPERTY(BlueprintReadOnly, Category = "WidgetController")
TObjectPtr<UAttributeSet> AttributeSet;
};
Controller의 경우에 Model과 View에 모두 접근해야 합니다.
따라서 둘 모두에 접근할 수 있도록 위와 같이 멤버를 구성하였습니다.
2) View에서도 개별 UI의 역할을 수행하는 AAuraUserWidget
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "AuraUserWidget.generated.h"
/**
*
*/
UCLASS()
class AURA_API UAuraUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
// Widget Controller를 설정하는 함수
UFUNCTION(BlueprintCallable)
void SetWidgetController(UObject* InWidgetController);
UPROPERTY(BlueprintReadOnly)
TObjectPtr<UObject> WidgetController;
protected:
// Widget Controller가 설정되면 호출하는 함수
UFUNCTION(BlueprintImplementableEvent)
void WidgetControllerSet();
};
#include "UI/Widgets/AuraUserWidget.h"
void UAuraUserWidget::SetWidgetController(UObject* InWidgetController)
{
WidgetController = InWidgetController;
WidgetControllerSet();
}
UserWidget의 경우 실제 제작은 C++ 클래스가 아닌 블루 프린트에서 이뤄집니다.
따라서 블루 프린트에서 함수를 다루고 호출할 수 있게 BlueprintImplementableEvent 지시자를 사용했습니다.
이제 각기 다른 UI 중에서 체력 UI를 만들기 위한 조상 체력 UI를 만들겠습니다.
언리얼 에디터에 넘어가서 아래와 같이 AuraUserWidget을 상속받은 Widget BP를 생성하겠습니다.
구성은 다음과 같습니다.
에서 이어져
로 끝나게 됩니다.
각각의 함수는 다음의 역할을 수행합니다.
1) InitBoxSize : SizeBox의 크기와 높이를 설정합니다.
2) InitBackgroundBrush : 배경인 황금색 원을 설정하고 그에 맞는 Slate Brush를 설정합니다.
3) InitGlobeImage : 체력이나 마나를 의미하는 Image를 설정합니다.
4) InitGlobePadding : 황금색 원과 체력이나 마나를 의미하는 Image의 간격을 조정합니다.
5) InitGlassBrush : 유리병 질감을 전달하는 유리병을 설정하고 Slate Brush를 설정합니다.
6) InitGlassPadding : 유리병의 간격을 조정합니다.
실제 완성된 결과는 다음과 같습니다.
완성결과를 통해 같은 UI에서 내용물만 다르게 설정한 다른 WBP를 만들 수 있습니다.