관리 메뉴

Mini

[UE5] OverlayWidgetController 구현 , HUD에서 사용할 정보들 로딩하기// newObject함수?, TScriptInterface 본문

카테고리 없음

[UE5] OverlayWidgetController 구현 , HUD에서 사용할 정보들 로딩하기// newObject함수?, TScriptInterface

Mini_96 2024. 5. 27. 03:32

1. 멤버변수

playercontroller , asc, as, ps 모두 가지고 사용해야함.

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;
};

 

2. 초기화 쉽게 구조체를 만듬

//UAuraWidgetController 맴버변수 쉽게 초기화하기 위한 구조체
USTRUCT(BlueprintType)
struct FWidgetControllerParams
{
	GENERATED_BODY()

protected:
	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; //구조체 멤버변수 초기화해줘야 warning 안뜸
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite);
	TObjectPtr<APlayerState> PlayerState=nullptr;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite);
	TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent=nullptr;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TObjectPtr<UAttributeSet> AttributeSet=nullptr;
	
};

3. 멤버변수에 매개변수로 받은 구조체들의 값들을 넣어주면됨

void UAuraWidgetController::SetWidgetControllerParams(const FWidgetControllerParams& WCParams)
{
	PlayerController=WCParams.PlayerController;
	PlayerState=WCParams.PlayerState;
	AbilitySystemComponent=WCParams.AbilitySystemComponent;
	AttributeSet=WCParams.AttributeSet;
}

 

4. 이걸 Base로 OverlayWidgetController 를 만듬

 

5. HUD에서 OverlayWidgetController를 의지함. 사용함.

컨트롤러는 1개만 있어야함 => 싱글톤으로 구현

UPROPERTY()
	TObjectPtr<UOverlayWidgetController> OverlayWidgetController;

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

		return OverlayWidgetController;
	}
	return OverlayWidgetController;
}

 

※ newObject함수? 

NewObject<타입>(소유자, 생성될타입)

NewObject() 가장 간단한 UObject 팩토리 메소드입니다. 선택적 외부 개체와 클래스를 가져와 자동으로 생성된 이름으로 새 인스턴스를 만듭니다.

template< class T >
T* NewObject
(
    UObject* Outer=(UObject*)GetTransientPackage(),
    UClass* Class=T::StaticClass() 
)

매개변수설명

Outer
  1. UObject 생성되는 객체의 외부로 설정할 A입니다 . //생성된 오브젝트를 소유하는 객체
Class
  1. UClass 생성할 개체의 클래스를 지정하는 A입니다 .

 

 

6. 위젯, 위젯컨트롤러를 만들고, 위젯을 뷰포트에 추가

//위젯컨트롤러구성, 위젯 구성, 뷰포트에 추가하는 함수
void AAuraHUD::InitOverlay(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS)
{
	//BP에서 클래스를 안넣어준경우 예외처리, 실패시 문자열프린트
	checkf(OverlayWidgetClass, TEXT("Overlay Widget Class uninitialized, please fill out BP_AuraHUD"));
	checkf(OverlayWidgetControllerClass, TEXT("Overlay Widget Controller Class uninitialized, please fill out BP_AuraHUD"));

	//위젯생성 (OevelayWidgetClass는 BP에서 넣어준 구체적 대상이 들어감)
	UUserWidget* Widget = CreateWidget<UUserWidget>(GetWorld(),OverlayWidgetClass);
	OverlayWidget=Cast<UAuraUserWidget>(Widget);
	
	//컨트롤러생성
	const FWidgetControllerParams WidgetControllerParams(PC,PS,ASC,AS);
	UOverlayWidgetController* WidgetController = GetOverlayWidgetController(WidgetControllerParams);

	//위젯에 컨트롤러 set하기
	OverlayWidget->SetWidgetController(WidgetController);
	WidgetController->BroadcastInitialValues(); //뷰포트추가전에 방송
	Widget->AddToViewport();
}

* 언제 이 함수를 실행해야하나? == 언제 모든 변수들이 null 이 아닌가?

PC, PS, ASC, AS가 모두 초기화 된 이후에 실행되야함

* AuraCharacter.cpp 에서 InitAbiliryActorInfo()함수가 있음

-> PC, PS, ASC, AS 가 모두 존재함 -> 여기서 실행!

//멀티플레이어서 null가능성 있음
	AAuraPlayerController* AuraPlayerController = Cast<AAuraPlayerController>(GetController());
	if (AuraPlayerController)
	{
    //HUD는 로컬로제어되는 플레이어에게만 유효함
		if (AAuraHUD* AuraHUD = Cast<AAuraHUD>(AuraPlayerController->GetHUD()))
		{
			AuraHUD->InitOverlay(AuraPlayerController, AuraPlayerState, AbilitySystemComponent, AttributeSet);
		}
	}

* PC가 항상 null이 아닌가?

예외처리해줘야함) because 2인용 철권에서 2p의 pc는 null임!

 

7. 초기화 잘 됬는지 확인 

HUD에서 breakpoint로 확인해보면

모든 변수들이 잘 초기화 된것을 볼 수있다.

이 정보들을 이용해서 뷰에 찍어주면 되는것이다!

 

+ TScriptInterface

언리얼5 표준에 맞춰 InterfacePtr을 수정하였다.


- 설명

TScriptInterface InterfaceType 네이티브 인터페이스 클래스를 구현하는 UObject에 대한 포인터입니다.