관리 메뉴

Mini

[UE5] 메뉴 위젯 컨트롤러 구현, BP내 사용가능한 위젯컨트롤러 게터 만들기, BP 상속안될때 해결방법, MVC 정리 본문

UE5/Attribute Menu

[UE5] 메뉴 위젯 컨트롤러 구현, BP내 사용가능한 위젯컨트롤러 게터 만들기, BP 상속안될때 해결방법, MVC 정리

Mini_96 2024. 6. 8. 03:16

* 이전에 어떻게 했더라?

HUD에서 위젯컨트롤러를 가지고있고,

Getter도 가지고 있음

이를 따라할것임

class AURA_API AAuraHUD : public AHUD
{
    GENERATED_BODY()
public:
    UPROPERTY()
    TObjectPtr<UAuraUserWidget>  OverlayWidget;

    //Getter임
    UOverlayWidgetController* GetOverlayWidgetController(const FWidgetControllerParams& WCParams);

    void InitOverlay(APlayerController* PC, APlayerState* PS , UAbilitySystemComponent* ASC, UAttributeSet* AS);



protected:


private:

    UPROPERTY(EditAnywhere)
    TSubclassOf<UAuraUserWidget> OverlayWidgetClass;

    UPROPERTY()
    TObjectPtr<UOverlayWidgetController> OverlayWidgetController;

    UPROPERTY(EditAnywhere)
    TSubclassOf<UOverlayWidgetController> OverlayWidgetControllerClass;
};
UOverlayWidgetController* AAuraHUD::GetOverlayWidgetController(const FWidgetControllerParams& WCParams)
{
    if(OverlayWidgetController == nullptr)
    {
       //(연결될클래스 , 생성될타입)
       //Outer : 생성될 오브젝트를 소유하는 UObject 객체
       //Class : 생성될 오브젝트의 클래스를 나타내는 UClass 정보
       OverlayWidgetController=NewObject<UOverlayWidgetController>(this,OverlayWidgetControllerClass);
       OverlayWidgetController->SetWidgetControllerParams(WCParams);
       OverlayWidgetController->BindCallbacksToDependencies();
       
       return OverlayWidgetController;
    }
    return OverlayWidgetController;
}

 

* 목표 : BP내 사용가능한 위젯컨트롤러 게터 만들기

아래처럼 WBP_속성메뉴 에서 바로 나타나길 바람

 

c++ 만들기

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "AuraAbilitySystemLibrary.generated.h"

class UOverlayWidgetController;
/**
 * 
 */
UCLASS()
class AURA_API UAuraAbilitySystemLibrary : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()

public:

    UFUNCTION(BlueprintPure, Category="AuraAbilitySystemLibrary|WidgetController")
    static UOverlayWidgetController* GetOverlayWidgetController(const UObject* WorldContextObject);
    //스태틱 => 월드정보를 얻을방법이없음 -> 월드에서 정보얻음
    
};

@Getter 만들기

// Fill out your copyright notice in the Description page of Project Settings.


#include "AbilitySystem/AuraAbilitySystemLibrary.h"
#include "Kismet/GameplayStatics.h"
#include "UI/WidgetController/AuraWidgetController.h"
#include "Player/AuraPlayerState.h"
#include "UI/HUD/AuraHUD.h"

UOverlayWidgetController* UAuraAbilitySystemLibrary::GetOverlayWidgetController(const UObject* WorldContextObject)
{
    //1. PC 얻기
    if(APlayerController* PC = UGameplayStatics::GetPlayerController(WorldContextObject,0))
    {
       //PC에서는 HUD에 항상접근가능
       if(AAuraHUD* AuraHUD = Cast<AAuraHUD>(PC->GetHUD()))
       {
          //PC에서 PS 얻기
          //PS에서 ASC, AS 얻기
          AAuraPlayerState* PS = PC->GetPlayerState<AAuraPlayerState>();
          auto ASC = PS->GetAbilitySystemComponent();
          auto AS = PS->GetAttributeSet();
          const FWidgetControllerParams WidgetControllerParams(PC,PS,ASC,AS); //4총사가 필요함
          return AuraHUD->GetOverlayWidgetController(WidgetControllerParams); //HUD에는 위젯컨트롤러 getter가있고 매개변수로
       }
    }
    return nullptr;
}

결과

 

* 위젯메뉴컨트롤러 BP 게터만들기

HUD에 멤버변수추가

UPROPERTY()
TObjectPtr<UAttributeMenuWidgetController> AttributeMenuWidgetController;

UPROPERTY(EditAnywhere)
TSubclassOf<UAttributeMenuWidgetController> AttributeMenuWidgetControllerClass;

게터구현

UAttributeMenuWidgetController* AAuraHUD::GetAttributeMenuWidgetController(const FWidgetControllerParams& WCParams)
{
    if(AttributeMenuWidgetController == nullptr)
    {
       //(연결될클래스 , 생성될타입)
       //Outer : 생성될 오브젝트를 소유하는 UObject 객체
       //Class : 생성될 오브젝트의 클래스를 나타내는 UClass 정보
       AttributeMenuWidgetController=NewObject<UAttributeMenuWidgetController>(this,AttributeMenuWidgetControllerClass);
       AttributeMenuWidgetController->SetWidgetControllerParams(WCParams); //부모인 아우라위젯컨틀롤러의 함수
       AttributeMenuWidgetController->BindCallbacksToDependencies();
       
       return AttributeMenuWidgetController;
    }
    return AttributeMenuWidgetController;
}

BP용 클래스에서도 Getter 구현

UAttributeMenuWidgetController* UAuraAbilitySystemLibrary::GetAttributeMenuWidgetController(
    const UObject* WorldContextObject)
{
    //1. PC 얻기
    if(APlayerController* PC = UGameplayStatics::GetPlayerController(WorldContextObject,0))
    {
       //PC에서는 HUD에 항상접근가능
       if(AAuraHUD* AuraHUD = Cast<AAuraHUD>(PC->GetHUD()))
       {
          //PC에서 PS 얻기
          //PS에서 ASC, AS 얻기
          AAuraPlayerState* PS = PC->GetPlayerState<AAuraPlayerState>();
          auto ASC = PS->GetAbilitySystemComponent();
          auto AS = PS->GetAttributeSet();
          const FWidgetControllerParams WidgetControllerParams(PC,PS,ASC,AS); //4총사가 필요함
          return AuraHUD->GetAttributeMenuWidgetController(WidgetControllerParams); //HUD에는 위젯컨트롤러 getter가있고 매개변수로
       }
    }
    return nullptr;
}

 

* BP 상속안될때 해결방법

blueprinttype, blueprintable 넣어주면 된다.

UCLASS(BlueprintType, Blueprintable)
class AURA_API UAttributeMenuWidgetController : public UAuraWidgetController
{
	GENERATED_BODY()

위클래스를 상속받은 BP 만들수 있게됨

 

* HUD를 보면, 여기 클래스 의존성주입을 해줘야함 (BP에서)

UPROPERTY(EditAnywhere)
TSubclassOf<UAttributeMenuWidgetController> AttributeMenuWidgetControllerClass;

속성menu컨트롤러를 속성menu위젯의 컨트롤러로 설정

* 잘 설정됬는지 확인

디버깅용 코드
속성버튼을 누르면 로그가 찍힘

 *  MVC 정리

- 위젯 : 컨트롤러를 가짐

- 컨트롤러 : 데이터(PC,PS,ASC,AS) 를가짐

-> 즉, 위젯에서 컨트롤러를 통해 데이터들에 접근 가능해짐!!

콜백함수에서 모든 정보를 방송가능함!