
이제 만들어둔 HP바의 부모클래스인 유저 위젯을 상속받는 C++클래스를 만들어주자.

이때 블루프린트에서 ProgressBar로 HP바를 정의해뒀는데 이 C++ 클래스에서 똑같은 이름으로 바인딩을 UPROPERTY로 해줄 수 있다.
HealthBar.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "HealthBar.generated.h"
/**
*
*/
UCLASS()
class SLASH_API UHealthBar : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(meta = (BindWidget))
class UProgressBar* HealthBar;
};
Enemy클래스에서 블루프린트 객체를 호출하기 위해 부모 객체의 GetUserWidgetObject함수를 사용할 수 있다.
이렇게 해주고 블루프린트 상에서 부모클래스를 HealthBar로 바꿔주자.

이제 코드상에서 이 위젯을 호출하고 ProgressBar의 속성을 변경할 수 있게 하자.
일단 퍼센트에 따라 체력바가 조정되게 해야한다. 이때 UWidgetComponent에서 자신의 유저 위젯을 반환해주는 함수를
사용해서 현재 사용자 위젯을 가져올 수 있다. 이때 이 함수는 UUserWidget을 반환해주데 우리가 필요한 것은 HealthBar이기 때문에 캐스팅을 해주어야한다.

이때 캐스팅이 여러번 이루어지지 않도록 멤버변수를 활용해주자. 그리고 UPROPERTY를 활용해서 기본값에 가비지 값이 할당되지 않도록 하자.
HealthBarComponent.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/WidgetComponent.h"
#include "HealthBarComponent.generated.h"
/**
*
*/
UCLASS()
class SLASH_API UHealthBarComponent : public UWidgetComponent
{
GENERATED_BODY()
public:
void SetHealthPercent(float Percent);
private:
UPROPERTY()
class UHealthBar* HealthBarWidget;
};
HealthBarComponent.cpp
void UHealthBarComponent::SetHealthPercent(float Percent)
{
if (HealthBarWidget == nullptr)
{
HealthBarWidget = Cast<UHealthBar>(GetUserWidgetObject());
}
if (HealthBarWidget && HealthBarWidget->HealthBar)
{
HealthBarWidget->HealthBar->SetPercent(Percent);
}
}
이렇게 유저위젯관련 코드를 작성해주었으니 Enemy 클래스에서 멤버변수의 타입도 바꿔주고 생성자에서 CreateDefaultSubObject의 클래스명을 바꿔주고 BeginPlay에서 이를 호출하여 테스트해보자.
Enemy.h
private:
UPROPERTY(VisibleAnywhere)
class UHealthBarComponent* HealthBarWidget;
Enemy.cpp
AEnemy::AEnemy()
{
PrimaryActorTick.bCanEverTick = true;
GetMesh()->SetCollisionObjectType(ECollisionChannel::ECC_WorldDynamic);
GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Visibility, ECollisionResponse::ECR_Block);
GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
GetMesh()->SetGenerateOverlapEvents(true);
GetCapsuleComponent()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
Attributes = CreateDefaultSubobject<UAttributeComponent>(TEXT("Attributes"));
HealthBarWidget = CreateDefaultSubobject<UHealthBarComponent>(TEXT("HealthBar"));
HealthBarWidget->SetupAttachment(GetRootComponent());
}
void AEnemy::BeginPlay()
{
Super::BeginPlay();
if (HealthBarWidget)
{
HealthBarWidget->SetHealthPercent(.1f);
}
}
정상적으로 작동하는 것을 볼 수 있다.

'게임공부 > Unreal Engine' 카테고리의 다른 글
[Unreal Engine][C++]22. Death (1) | 2025.01.26 |
---|---|
[Unreal Engine][C++]21. Damage (1) | 2025.01.21 |
[Unreal Engine][C++]19. Actor Component (0) | 2025.01.14 |
[Unreal Engine][C++]18. Treasure2 (0) | 2025.01.03 |
[Unreal Engine][C++]17. Treasure (0) | 2025.01.03 |