HUD와 기존 위젯 컴포넌트의 차이점
위젯 컴포넌트를 통해 생성한 몬스터 HPBar는 GetOwningPlayerPawn함수를 통해 UI를 소유하고 있는
폰을 가져오려면 위 스크린샷과 같이 에러가 발생한다. 그래서 위젯 컴포넌트에서 위젯이 초기화 될때
위젯에 오너를 넘겨 오너를 사용해야 된다.
HUD위젯은 플레이어 컨트롤러에 생성을 한다. 그래서 문제없이 GetOwningPlayerPawn 함수를
사용할 수 있다
위젯 제작
C++ 클래스 생성
UserWidget을 상속받아 PPPLayerStatBarUserWidget, PPHUDWidget을 생성한다
위젯 블루프린트 생성
PPPLayerStatBarUserWidget을 상속받아 위젯 블루프린트를 생성하여 HPBar, MPBar를 프로그래스바와 텍스트를 이용하여 생성한다
PPHUDWidget을 상속받은 위젯 블루프린트를 생성한다
HUD는 캔버스 패널을 추가한 다음 Palette→User Created에서 생성한 PPPLayerStatBarUserWidget을 캔버스에 적절한 위치에 넣는다
UPPPlayerStatBarUserWidget
헤더파일
#include "CoreMinimal.h"
#include "UI/PPGASUserWidget.h"
#include "GameplayEffectTypes.h"
#include "PPPlayerStatBarUserWidget.generated.h"
/**
*
*/
UCLASS()
class PROJECT_P_API UPPPlayerStatBarUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
UPPPlayerStatBarUserWidget(const FObjectInitializer& ObjectInitializer);
protected:
virtual void NativeConstruct() override;
void OnHealthAttributeChange(const FOnAttributeChangeData& ChangeData);
void OnMaxHealthAttributeChange(const FOnAttributeChangeData& ChangeData);
void OnManaAttributeChange(const FOnAttributeChangeData& ChangeData);
void OnMaxManaAttributeChange(const FOnAttributeChangeData& ChangeData);
void UpdateHpBar();
void UpdateMpBar();
UPROPERTY(meta = (BindWidget))
TObjectPtr<class UProgressBar> PbHpBar;
UPROPERTY(meta = (BindWidget))
TObjectPtr<class UProgressBar> PbMpBar;
UPROPERTY(meta = (BindWidget))
TObjectPtr<class UTextBlock> TxtHpStat;
UPROPERTY(meta = (BindWidget))
TObjectPtr<class UTextBlock> TxtMpStat;
private:
float CurrentHealth = 0.0f;
float CurrentMaxHealth = 0.0f;
float CurrentMana = 0.0f;
float CurrentMaxMana = 0.0f;
};
- UPPPlayerStatBarUserWidget(const FObjectInitializer& ObjectInitializer);
- 위젯 클래스의 생성자
- 위젯 클래스는 기본 생성자가 없고 FObjectInitializer를 매개변수로 하는 생성자만 존재
- virtual void NativeConstruct() override;
- 위젯이 AddToViewport 함수가 실행되면 호출되는 함수
- void OnHealthAttributeChange(const FOnAttributeChangeData& ChangeData);
void OnMaxHealthAttributeChange(const FOnAttributeChangeData& ChangeData);
- HP, MP 어트리뷰트가 바뀔때 실행되는 델리게이트에 연결할 콜백함수들
- void UpdateHpBar();
void UpdateMpBar();- HP, MP가 변경되면 실행할 함수들
- UPROPERTY(meta = (BindWidget))
TObjectPtr<class UProgressBar> PbHpBar;
UPROPERTY(meta = (BindWidget))
TObjectPtr<class UTextBlock> TxtHpStat;
- UPROPERTY(meta = (BindWidget)) 설정으로 블루프린트 위젯 변수명이랑 동일하게 변수명을 설정하면 자동으로 위젯을 바인드 해줌
생성자
UPPPlayerStatBarUserWidget::UPPPlayerStatBarUserWidget(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
}
위젯 생성자는 Super()로 매개변수를 부모한테 넘겨줘야 함
NativeConstruct
void UPPPlayerStatBarUserWidget::NativeConstruct()
{
UAbilitySystemComponent* ASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(GetOwningPlayerPawn());
if (ASC)
{
ASC->GetGameplayAttributeValueChangeDelegate(UPPCharacterAttributeSet::GetHealthAttribute()).
AddUObject(this, &UPPPlayerStatBarUserWidget::OnHealthAttributeChange);
ASC->GetGameplayAttributeValueChangeDelegate(UPPCharacterAttributeSet::GetMaxHealthAttribute()).
AddUObject(this, &UPPPlayerStatBarUserWidget::OnMaxHealthAttributeChange);
ASC->GetGameplayAttributeValueChangeDelegate(UPPCharacterAttributeSet::GetManaAttribute()).
AddUObject(this, &UPPPlayerStatBarUserWidget::OnManaAttributeChange);
ASC->GetGameplayAttributeValueChangeDelegate(UPPCharacterAttributeSet::GetMaxManaAttribute()).
AddUObject(this, &UPPPlayerStatBarUserWidget::OnMaxManaAttributeChange);
const UPPCharacterAttributeSet* AttributeSet = ASC->GetSet<UPPCharacterAttributeSet>();
if (AttributeSet)
{
CurrentHealth = AttributeSet->GetHealth();
CurrentMaxHealth = AttributeSet->GetMaxHealth();
if (CurrentMaxHealth > 0.0f)
{
UpdateHpBar();
}
CurrentMana = AttributeSet->GetMana();
CurrentMaxMana = AttributeSet->GetMaxMana();
if (CurrentMaxMana > 0.0f)
{
UpdateMpBar();
}
}
}
}
- UAbilitySystemComponent* ASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(GetOwningPlayerPawn());
- GetOwningPlayerPawn 함수로 위젯을 소유하고있는 폰을 가져와 ASC를 가져옴
- ASC->GetGameplayAttributeValueChangeDelegate(UPPCharacterAttributeSet::GetHealthAttribute()).
AddUObject(this, &UPPPlayerStatBarUserWidget::OnHealthAttributeChange);- 어트리뷰트셋을 사용하고 있으면 ASC에서 어트리뷰트가 바뀔때마다 호출되는 델리게이트를 지원해줌
- 콜백함수를 연결
- const UPPCharacterAttributeSet* AttributeSet = ASC->GetSet<UPPCharacterAttributeSet>();
- ASC를 이용해 어트리뷰트셋을 가져옴
- CurrentHealth = AttributeSet->GetHealth();
CurrentMaxHealth = AttributeSet->GetMaxHealth();- 어트리뷰트셋에서 스탯을 가져옴
- if (CurrentMaxHealth > 0.0f)
{
UpdateHpBar();
}- 스텟을 잘가져왔으면 UpdateHpBar로 UI에 반영
OnHealthAttributeChange
void UPPPlayerStatBarUserWidget::OnHealthAttributeChange(const FOnAttributeChangeData& ChangeData)
{
CurrentHealth = ChangeData.NewValue;
UpdateHpBar();
}
- CurrentHealth = ChangeData.NewValue;
- ChangeData로 바뀐 어트리뷰트 값을 반영
- UpdateHpBar();
- UI 업데이트
- 다른 어트리뷰트들도 이와같이 함수를 작성
UpdateHpBar
void UPPPlayerStatBarUserWidget::UpdateHpBar()
{
if (PbHpBar)
{
PbHpBar->SetPercent(CurrentHealth / CurrentMaxHealth);
}
if (TxtHpStat)
{
TxtHpStat->SetText(FText::FromString(FString::Printf(TEXT("%.0f/%0.f"), CurrentHealth, CurrentMaxHealth)));
}
}
변경된 값들을 프로그래스 바와 텍스트에 적용
UPPHUDWidget
헤더파일
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "PPHUDWidget.generated.h"
/**
*
*/
UCLASS()
class PROJECT_P_API UPPHUDWidget : public UUserWidget
{
GENERATED_BODY()
public:
UPPHUDWidget(const FObjectInitializer& ObjectInitializer);
protected:
virtual void NativeConstruct() override;
UPROPERTY(meta = (BindWidget))
TObjectPtr<class UPPPlayerStatBarUserWidget> PlayerStatBar;
};
- UPROPERTY(meta = (BindWidget))
TObjectPtr<class UPPPlayerStatBarUserWidget> PlayerStatBar;- 블루프린트에서 생성한 위젯을 변수로 생성 및 바인드
HUDWidget에서는 하위 위젯에서 기능을 구현하여 별도로 구현할 필요가 없음
'포트폴리오 제작' 카테고리의 다른 글
Project_P 행동트리 모델 공격방향으로 로테이션 (0) | 2024.12.18 |
---|---|
Project_P 몬스터 HPBar 기능 추가 (0) | 2024.12.18 |
Project_P 행동트리 모델 데코레이터 및 테스크 생성 (0) | 2024.12.10 |
Project_P 행동트리 모델 AI Perception (0) | 2024.12.09 |
Project_P 행동트리 모델 NPC 정찰 구현 (1) | 2024.12.06 |