Mini
[UE5] OverlayWidgetController 구현 , HUD에서 사용할 정보들 로딩하기// newObject함수?, TScriptInterface 본문
[UE5] OverlayWidgetController 구현 , HUD에서 사용할 정보들 로딩하기// newObject함수?, TScriptInterface
Mini_96 2024. 5. 27. 03:321. 멤버변수
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 |
|
Class |
|
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에 대한 포인터입니다. |