필요한 개념
<Enemy HP UI 만들기>
* CStatusComponent에 Health 변수 추가하기
UPROPERTY(EditDefaultsOnly, Category = "Health")
float MaxHealth = 100.0f;
private:
float Health;
// CStatusComponent.cpp
// Health에 MaxHealth 넣어주기
Health = MaxHealth;
<위젯 추가하기>
* 위젯 2개를 출력할 것이다.
1. Name
2. HP
-> UserWidget기반 Class를 만들고 이를 기반으로 한 WidgetBP 만들어서 연결해주면 됨
// CUsetWidget_Name.h
// 이름 세팅가능하도록 BP에서 재정의하도록 함
UFUNCTION(BlueprintImplementableEvent)
void SetNameText(const FString& InName);
* 이 클래스를 기반하여 WB_Name 생성
컨트롤러의 이름과 캐릭터 이름을 모두 출력하도록 작업
그래프 레이아웃을 Desired On Screen으로 실제로 어떻게 나타나는지 확인가능(어느 크키인지 실감 가능)
* WB_Name 이벤트 그래프 구현
Replace : 입력받은 문자열에서 From 문자열과 일칫하는 문자열을 To문자열로 바꿔주는 함수
BP_CEnemy_ 문자를 없애기 위해
* UserWidget기반 CUserWidget_Health 클래스도 생성
이 클래스는 HP바 갱신할 클래스
Update()는 BeginPlay할 때 한번 해주고, Enemy가 Hitted 상태일 때, 한번 처리해주면 된다.
// CUserWidget_Health.h
// BP에서 재정의 함
UFUNCTION(BlueprintImplementableEvent)
void Update(float Health, float MaxHealth);
* 이 클래스를 기반한 WB_Health BP 생성 및 Update() 함수 정의
* CEnemy에 2개의 WidgetBP 연결해줌
// CEnemy.h
protected:
UPROPERTY(VisibleDefaultsOnly)
class UWidgetComponent* NameWidget;
UPROPERTY(VisibleDefaultsOnly)
class UWidgetComponent* HealthWidget;
// CEnemy.cpp 생성자
// Widget은 Mesh()에다가 붙이면 된다.
CHelpers::CreateComponent<UWidgetComponent>(this, &NameWidget, "NameWidget", GetMesh());
CHelpers::CreateComponent<UWidgetComponent>(this, &HealthWidget, "HealthWidget", GetMesh());
* NameClass 로드
// WidgetClass 설정(TSubClassof UserWidget을 상속받은 애들만 가능)
TSubclassOf<UCUserWidget_Name> nameClass;
CHelpers::GetClass<UCUserWidget_Name>(&nameClass, "WidgetBlueprint'/Game/Widgets/WB_Name.WB_Name_C'");
// SetWidgetClass하면 WidgetComponent에서 이 위젯 객체를 만듬
// 나중에 GetWidgetObject()로 가져올 수 있음
NameWidget->SetWidgetClass(nameClass);
NameWidget->SetRelativeLocation(FVector(0, 0, 240));
// 크기 설정
NameWidget->SetDrawSize(FVector2D(240, 30));
// 화면 공간에 띄울껀지(Screen으로 해서 항상 정면에서 볼 수 있도록 함)
NameWidget->SetWidgetSpace(EWidgetSpace::Screen);
* HealthClass 로드
TSubclassOf<UCUserWidget_Health> healthClass;
CHelpers::GetClass<UCUserWidget_Health>(&healthClass, "WidgetBlueprint'/Game/Widgets/WB_Health.WB_Health_C'");
HealthWidget->SetWidgetClass(healthClass);
HealthWidget->SetRelativeLocation(FVector(0, 0, 190));
HealthWidget->SetDrawSize(FVector2D(120, 20));
HealthWidget->SetWidgetSpace(EWidgetSpace::Screen);
// CEnemy.cpp BeginPlay
// InitWidget() : 위젯을 초기화시키는 함수
// 안하면 가끔 콜이 안될때가 있음
NameWidget->InitWidget();
// GetUserWidgetObject() : UserWidgetclass로 세팅된 자료형에 대해 자동으로 만들어진 객체 리턴
Cast<UCUserWidget_Name>(NameWidget->GetUserWidgetObject())->SetNameText(GetActorLabel());
HealthWidget->InitWidget();
Cast<UCUserWidget_Health>(HealthWidget->GetUserWidgetObject())->Update(Status->GetHealth(), Status->GetMaxHealth());
CStatusComponent.h 추가된 내용
더보기
#pragma once
...
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class UONLINE_04_ACTION_API UCStatusComponent : public UActorComponent
{
GENERATED_BODY()
private:
UPROPERTY(EditDefaultsOnly, Category = "Health")
float MaxHealth = 100.0f;
public:
FORCEINLINE float GetMaxHealth() { return MaxHealth; }
FORCEINLINE float GetHealth() { return Health; }
public:
...
void AddHealth(float InAmount);
// Health를 줄이는 것
void SubHealth(float InAmount);
private:
float Health;
};
CStatusComponent.cpp 추가된 내용
더보기
...
void UCStatusComponent::BeginPlay()
{
Super::BeginPlay();
Health = MaxHealth;
}
void UCStatusComponent::AddHealth(float InAmount)
{
Health += InAmount;
// Clamp : X가 Max보다 크면 Max로 제한,
// X가 Min보다 작으면 Min으로 제한
Health = FMath::Clamp(Health, 0.0f, MaxHealth);
}
void UCStatusComponent::SubHealth(float InAmount)
{
Health -= InAmount;
Health = FMath::Clamp(Health, 0.0f, MaxHealth);
}
CUserWidget_Name.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "CUserWidget_Name.generated.h"
UCLASS()
class UONLINE_04_ACTION_API UCUserWidget_Name : public UUserWidget
{
GENERATED_BODY()
public:
// 이름 세팅가능하도록 BP에서 재정의하도록 함
UFUNCTION(BlueprintImplementableEvent)
void SetNameText(const FString& InName);
};
CUserWidget_Health.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "CUserWidget_Health.generated.h"
UCLASS()
class UONLINE_04_ACTION_API UCUserWidget_Health : public UUserWidget
{
GENERATED_BODY()
public:
// BP에서 재정의 함
UFUNCTION(BlueprintImplementableEvent)
void Update(float Health, float MaxHealth);
};
CEnemy.h 추가된 내용
더보기
#pragma once
...
UCLASS()
class UONLINE_04_ACTION_API ACEnemy : public ACharacter, public IICharacter
{
GENERATED_BODY()
protected:
UPROPERTY(VisibleDefaultsOnly)
class UWidgetComponent* NameWidget;
UPROPERTY(VisibleDefaultsOnly)
class UWidgetComponent* HealthWidget;
};
CEnemy.cpp 추가된 내용
더보기
...
#include "Components/WidgetComponent.h"
#include "Widgets/CUserWidget_Name.h"
#include "Widgets/CUserWidget_Health.h"
ACEnemy::ACEnemy()
{
...
// WidgetClass 설정(TSubClassof UserWidget을 상속받은 애들만 가능)
TSubclassOf<UCUserWidget_Name> nameClass;
CHelpers::GetClass<UCUserWidget_Name>(&nameClass, "WidgetBlueprint'/Game/Widgets/WB_Name.WB_Name_C'");
// SetWidgetClass하면 WidgetComponent에서 이 위젯 객체를 만듬
// 나중에 GetWidgetObject()로 가져올 수 있음
NameWidget->SetWidgetClass(nameClass);
NameWidget->SetRelativeLocation(FVector(0, 0, 240));
// 크기 설정
NameWidget->SetDrawSize(FVector2D(240, 30));
// 화면 공간에 띄울껀지(Screen으로 해서 항상 정면에서 볼 수 있도록 함)
NameWidget->SetWidgetSpace(EWidgetSpace::Screen);
TSubclassOf<UCUserWidget_Health> healthClass;
CHelpers::GetClass<UCUserWidget_Health>(&healthClass, "WidgetBlueprint'/Game/Widgets/WB_Health.WB_Health_C'");
HealthWidget->SetWidgetClass(healthClass);
HealthWidget->SetRelativeLocation(FVector(0, 0, 190));
HealthWidget->SetDrawSize(FVector2D(120, 20));
HealthWidget->SetWidgetSpace(EWidgetSpace::Screen);
}
void ACEnemy::BeginPlay()
{
...
// InitWidget() : 위젯을 초기화시키는 함수
// 안하면 가끔 콜이 안될때가 있음
NameWidget->InitWidget();
// GetUserWidgetObject() : UserWidgetclass로 세팅된 자료형에 대해 자동으로 만들어진 객체 리턴
Cast<UCUserWidget_Name>(NameWidget->GetUserWidgetObject())->SetNameText(GetActorLabel());
HealthWidget->InitWidget();
Cast<UCUserWidget_Health>(HealthWidget->GetUserWidgetObject())->Update(Status->GetHealth(), Status->GetMaxHealth());
Action->SetUnarmedMode();
}
결과
'Unreal Engine 4 > C++' 카테고리의 다른 글
<Unreal C++> 53 - Action RPG(Juice(타격감)) (0) | 2022.05.16 |
---|---|
<Unreal C++> 51 - Action RPG(Enemy Hitted) (0) | 2022.05.16 |
<Unreal C++> 48 - Action RPG (Create Enemy & Collision) (0) | 2022.05.16 |
<Unreal C++> 47 - Action RPG (Character Interface) (0) | 2022.05.16 |
<Unreal C++> 46 - Action RPG (Melee Attack Combo) (0) | 2022.05.16 |