01 아이템박스 클래스와 블루프린트 생성 및 배치
box class를 만들어주고, 블루프린트도 하나 만들어주고 레벨에 배치해준다.
플레이어가 총알을 발사해 저 아이템 박스에 닿으면 hp가 깎이는걸 눈으로 보이게까지 구현할 것이다.
02 위젯 블루프린트 생성
아이템 박스 위에 띄울 위젯을 만들어준 후 아이템박스 BP 클래스에 이 위젯을 할당시켜줄 것이다.
위젯 컴포넌트 변수를 만들어주고,
//위젯 클래스의 변수
UPROPERTY()
class UItemBoxWidget* boxWidget;
//위젯 컴포넌트
UPROPERTY(EditDefaultsOnly)
class UWidgetComponent* widgetComp;
그 컴포넌트 안에 위젯 블루프린트를 넣어주었다.
widgetComp = CreateDefaultSubobject<UWidgetComponent>(TEXT("widgetComp"));
widgetComp->SetupAttachment(RootComponent);
widgetComp->SetWidgetSpace(EWidgetSpace::Screen);
ConstructorHelpers::FClassFinder<UUserWidget> hpWidget(TEXT("/Script/UMGEditor.WidgetBlueprint'/Game/ThirdPerson/Blueprints/WBP_ItemBox.WBP_ItemBox_C'"));
if(hpWidget.Succeeded())
{
widgetComp->SetWidgetClass(hpWidget.Class);
}
EWidgetSpace::Screen으로 설정하면 아이템박스의 어느 방향에서 보아도 위젯이 보이고,
EWidgetSpace::World로 설정하면 지정된 방향에서만 위젯이 보인다.
위젯 블루프린트를 만들 때는 c++ 클래스 우클릭한 후 위젯 블루프린트를 만들지 말고
블루프린트 클래스를 만든 후 위젯C++ 클래스로 Reparent 해주는 것을 추천한다.
위젯 편집할 수 있는 캔버스 화면이 안뜬다.
03 HP가 깎이는 부분 구현하기
//hp
int32 hp;
int32 maxHP = 10;
UFUNCTION(BlueprintCallable)
FORCEINLINE void TakeHP(int32 pwer) { maxHP -= pwer; }
아이템 박스의 hp 변수와 최대 hp 변수 값을 만들어준다.
일정 데미지가 발생하게되면 max hp에서 값이 깎이도록 inline 함수를 만들어주었다. 이렇게 간단하게 구현할 수 있는 것들은 인라인 함수로 구현할 수도 있지만, 현업에서는 인라인 함수가 간혹 찾기 힘들기 때문에 경우에 따라 불편함이 발생하다고도 한다. 하지만 이 블로그에서 등장한 적이 없으니까 이렇게 새로운걸 써보면서 스킬 늘려가기~
04 충돌할 때 HP가 깎이는 조건 추가하기
총알이 아이템박스에 닿았을 때 hp가 깎여야하기 때문에 Overlap 함수를 써주어야한다.
먼저 충돌 함수를 beginplay에서 바인딩 해주고, 게임 플레이할 때 최초 hp는 maxhp값과 같다고 지정해준다.
이렇게 하면 나중에 위젯이 활성화 되었을 때 처음 보여지는 모습은 hp가 꽉 찬 모습이다.
boxComp->OnComponentBeginOverlap.AddDynamic(this, &AItemBox::OnOverlap);
hp = maxHP;
헤더파일에 UFUNCTION써주고 아래에 함수를 써준다. 매개변수 찾기 위해서 일부러 바인딩 먼저 해주었다.
UFUNCTION()
void OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
그 다음 실제 HP가 깎이는 부분을 구현할것이다.
void AItemBox::OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
bullet = Cast<ABullet>(OtherActor);
UE_LOG(LogTemp, Warning, TEXT("OnOverlap : %s"), *OtherActor->GetName())
if(bullet)
{
TakeHP(bullet->attkScore);
UE_LOG(LogTemp, Warning, TEXT("box hp : %d"), maxHP)
}
}
총알과 충돌하는지 확인도 해주고, HP가 잘 깎이는지도 확인하기 위해 로그를 남겼다.
bullet->attkScore의 변수는 어디서 나왔냐면, bullet의 헤더파일에 선언해준 변수이다.
int32 attkScore = 5;
05 위젯 클래스 만들기
UPROPERTY(EditDefaultsOnly, meta = (BindWidget))
class UProgressBar* hpBar;
UPROPERTY(EditDefaultsOnly, meta = (BindWidget))
class UTextBlock* txt_boxHP;
void ShowHPBar(float hp, float maxhp);
hp가 채워져 있는 공간을 어떻게 계산하도록 할 것인지 하는 것이고,
그 값이 얼마인가 숫자도 표현해줄 것이다.
#include "Components/ProgressBar.h"
#include "Components/TextBlock.h"
void UItemBoxWidget::ShowHPBar(float hp, float maxhp)
{
hpBar->SetPercent(maxhp / hp);
txt_boxHP->SetText(FText::AsNumber(maxhp / hp * 10));
}
지금은 간단하게 progressbar을 사용하고 있지만 프로그래스바 이미지를 만들어서 직접 삽입할 수도 있다. 적용하는 방법은 동일하다. 이미지를 삽입하는건 SetSlate였던 것으로 기억한다.
다른 프로젝트를 할 당시 예쁘게라도 만들고 싶어서 모서리가 둥근 사각형 이미지를 만들어 넣어줬었다.
그리고 위젯을 사용한다면 Build.cs에 들어가 UMG 모듈을 추가해주면 된다.
이 부분을 볼 때마다 C#도 반드시 공부해야겠다는 생각이 든다.
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "EnhancedInput", "UMG" });
06 HP가 깎이는 부분과 위젯 클래스가 연결되도록
아이템박스 클래스의 Beginplay로 가서
boxWidget = Cast<UItemBoxWidget>(widgetComp->GetWidget());
if (boxWidget)
{
boxWidget->ShowHPBar(hp, maxHP);
}
위젯클래스를 캐스팅한 후 hp 값을 계산하는 함수를 호출해준다.
widgetComp는 아이템박스에 있는 위젯 컴포넌트이고, boxWidget은 위젯 클래스이다.
'언리얼엔진 개발 > Developing' 카테고리의 다른 글
[UnrealEngine5] 위젯에 텍스트 넣는 법 C++ (0) | 2023.07.21 |
---|---|
[UnrealEngine5] 충돌했을 때 반응하는 오브젝트 만들기 C++ (0) | 2023.07.21 |
[UnrealEngine5]TPS 제작 환경에서의 LineTrace 사용하는 법 (0) | 2023.07.20 |
[UnrealEngine5]로컬라이징( Feat. 영어, 한국어 설정하기) (0) | 2023.07.19 |
[UnrealEngine5] 플레이어가 총알을 발사하게 하는 법 (0) | 2023.07.13 |