Unreal GAS (8) - Widget 구성 (MVC 모델)

wnsduf0000·2025년 12월 1일

Unreal_GAS

목록 보기
8/34
  • RPG Game UI Architecture 개요

    • 게임은 현재 플레이어의 상태 등의 여러 정보를 플레이어의 화면 위에 노출시켜야 한다.
      언리얼에서 이를 Widget이라는 수단으로 표현하며, UUserWidget 클래스를 상속한다.

    • 위젯은 플레이어에게 표현해주기 위한 데이터를 적절한 곳에서 참조해야 한다.
      문제는 게임은 데이터로 넘쳐나는 프로그램이고, 플레이어에게 노출시켜주기 위한 정보가 각기 다른 곳에 흩어져 있을 가능성이 높다는 것이다.
      예를 들어, 능력치 정보는 플레이어의 AbilitySystemComponent가 소유한 AttributeSet에 있을 것이며, 플레이어와 관련된 상태는 PlayerController에 있을 수도 있다.

    • 위젯이 필요한 정보를 가져오는 방법을 어떻게 설정해야 할까?

      • 위젯에서 필요로 하는 클래스를 직접 참조하여 가져오는 방법

        • 이는 가장 간편하게 구현할 수 있는 방법이지만, 게임의 규모가 커질수록 참조가 점점 더 복잡해진다. 규모가 어느 정도만 커져도 어느 위젯에서 어떤 클래스를 참조하고 있는지 기억하는 것조차 어려워 질 것이다.
      • 위젯과 데이터를 분리하여, 서로에 대해 알 필요 없이 정보를 참조하게 하는 방법.

        • 흔히 View - Model - Controller, 즉 MVC라 불리는 모델이다.

          • View는 플레이어가 보거나 상호작용하는 위젯 그 자체를 의미한다.
          • Model은 데이터 자체를 의미한다.
            이는 각종 능력치, 체력, 레벨 등을 포함할 수 있다.
            게임의 형태와 모습을 정하는 (모델링하는) 데이터들이므로 Model이라 부른다.
          • Controller는 모델의 데이터를 가져와, 뷰에게 알려주는
            중간자 역할을 하는 클래스로, 필요한 데이터 검색, 처리의 기능을 담당한다.
            (PlayerController 클래스를 말하는 것이 아님. 엄밀히 말하면 WidgetController)
        • 모델이 데이터를 보유한 형태에 관계 없이 컨트롤러는 이를 수신해야 하고,
          컨트롤러가 이를 어떻게 알리냐에 관계 없이 위젯이 존재해야 함.

          • UAuraUserWidget은 위젯 블루프린트들이 상속받을 클래스로,
            UAuraWidgetController와 상호작용하기 위한 기본 형태를 담고자 함.

            • AuraUserWidget & AuraWidgetController
    • 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;
      };
      • 게임 내 모든 위젯들이 상속받을 클래스이다.
        WidgetController에 대한 참조를 보유하고 있으며, WidgetController를 설정할 수 있는 함수가 존재한다. WidgetControllerSet은 별도의 처리가 추가로 필요한 경우 블루프린트에서 상속하여 구현할 수 있도록 하기 위한 함수이다.
    • 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);
      };
      
      • AuraWidgetController는 레벨 상에 위치를 가질 필요가 없으므로 UObject를 상속한 클래스로 만든다.
      • WidgetController는 데이터에 직접 접근 및 필요한 처리를 거쳐 데이터를 브로드캐스트하는 역할이므로, 필요로 하는 데이터(모델)에 대한 참조를 지녀야 한다.
        따라서 PlayerController, PlayerState, AbilitySystemComponent, AttributeSet에 대한 참조를 가져야 한다.
      • FWidgetControllerParams 구조체는 AuraWidgetController의 초기화를 더 편리하게 하기 위한 역할이다.
profile
저는 게임 개발자로 일하고 싶어요

0개의 댓글