RPG Game UI Architecture 개요
게임은 현재 플레이어의 상태 등의 여러 정보를 플레이어의 화면 위에 노출시켜야 한다.
언리얼에서 이를 Widget이라는 수단으로 표현하며, UUserWidget 클래스를 상속한다.
위젯은 플레이어에게 표현해주기 위한 데이터를 적절한 곳에서 참조해야 한다.
문제는 게임은 데이터로 넘쳐나는 프로그램이고, 플레이어에게 노출시켜주기 위한 정보가 각기 다른 곳에 흩어져 있을 가능성이 높다는 것이다.
예를 들어, 능력치 정보는 플레이어의 AbilitySystemComponent가 소유한 AttributeSet에 있을 것이며, 플레이어와 관련된 상태는 PlayerController에 있을 수도 있다.
위젯이 필요한 정보를 가져오는 방법을 어떻게 설정해야 할까?
위젯에서 필요로 하는 클래스를 직접 참조하여 가져오는 방법
위젯과 데이터를 분리하여, 서로에 대해 알 필요 없이 정보를 참조하게 하는 방법.
흔히 View - Model - Controller, 즉 MVC라 불리는 모델이다.

모델이 데이터를 보유한 형태에 관계 없이 컨트롤러는 이를 수신해야 하고,
컨트롤러가 이를 어떻게 알리냐에 관계 없이 위젯이 존재해야 함.

UAuraUserWidget은 위젯 블루프린트들이 상속받을 클래스로,
UAuraWidgetController와 상호작용하기 위한 기본 형태를 담고자 함.
AuraUserWidget
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "UI/WidgetController/AuraWidgetController.h"
#include "AuraUserWidget.generated.h"
UCLASS()
class AURA_API UAuraUserWidget : public UUserWidget
{
GENERATED_BODY()
protected:
UFUNCTION(BlueprintImplementableEvent)
void WidgetControllerSet();
public:
UFUNCTION(BlueprintCallable)
void SetWidgetController(UObject* InWidgetController);
UPROPERTY(BlueprintReadOnly)
TObjectPtr<UObject> WidgetController;
};
AuraWidgetController
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "AuraWidgetController.generated.h"
class UAbilitySystemComponent;
class UAttributeSet;
USTRUCT(BlueprintType)
struct FWidgetControllerParams
{
GENERATED_BODY()
FWidgetControllerParams() {}
FWidgetControllerParams(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS)
: PlayerController(PC), PlayerState(PS), AbilitySystemComponent(ASC), AttributeSet(AS) {}
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<APlayerController> PlayerController = nullptr;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<APlayerState> PlayerState = nullptr;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent = nullptr;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UAttributeSet> AttributeSet = nullptr;
};
UCLASS()
class AURA_API UAuraWidgetController : public UObject
{
GENERATED_BODY()
protected:
UPROPERTY(BlueprintReadOnly, Category = "WidgetController")
TObjectPtr<APlayerController> PlayerController;
UPROPERTY(BlueprintReadOnly, Category = "WidgetController")
TObjectPtr<APlayerState> PlayerState;
UPROPERTY(BlueprintReadOnly, Category = "WidgetController")
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
UPROPERTY(BlueprintReadOnly, Category = "WidgetController")
TObjectPtr<UAttributeSet> AttributeSet;
public:
UFUNCTION(BlueprintCallable)
void SetWidgetControllerParams(const FWidgetControllerParams& WCParams);
};