C++ 팀 과제 TIL (3)

정완훈·2025년 2월 21일

Unreal Engine에서 HUD에 최대 탄약량과 킬카운트 추가하기

이번 과제를 진행하다가 이전 PlayerHUD의 UpdateHUD에서 한번에 처리하지 말고 업데이트 하는 부분을 나눴으면 한다고 해서 바뀌었다. 바뀌는 김에 킬 카운트와 최대 탄약량을 추가했다.

1. 헤더 파일(CP_PlayerHUD.h) 수정

먼저 헤더 파일에서 최대 탄약량과 킬카운트를 위한 텍스트 블록을 추가한다. 기존에 업데이트 함수가 항목별로 분할되어 있는 구조를 유지하면서, 새로운 항목에 맞는 함수도 추가한다.

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Components/TextBlock.h"
#include "CP_PlayerHUD.generated.h"

UCLASS()
class CYBERPUNK_API UCP_PlayerHUD : public UUserWidget
{
    GENERATED_BODY()

public:
        UCP_PlayerHUD(const FObjectInitializer& ObjectInitializer);

    // 개별 업데이트 함수들
    UFUNCTION(BlueprintCallable, Category = "HUD")
    void UpdateWave(int32 Wave);

    UFUNCTION(BlueprintCallable, Category = "HUD")
    void UpdateWeaponName(const FString& WeaponName);

    UFUNCTION(BlueprintCallable, Category = "HUD")
    void UpdateAmmo(int32 Ammo);

    UFUNCTION(BlueprintCallable, Category = "HUD")
    void UpdateMaxAmmo(int32 MaxAmmo); // 최대 탄약량 업데이트 함수 추가

    UFUNCTION(BlueprintCallable, Category = "HUD")
    void UpdateHealth(int32 Health);

    UFUNCTION(BlueprintCallable, Category = "HUD")
    void UpdateEnemiesRemaining(int32 EnemiesRemaining);

    UFUNCTION(BlueprintCallable, Category = "HUD")
    void UpdateKillCount(int32 KillCount); // 킬카운트 업데이트 함수 추가

protected:
    virtual void NativeConstruct() override;

    // UMG 위젯 바인딩
    UPROPERTY(meta = (BindWidget))
    UTextBlock* WaveText;

    UPROPERTY(meta = (BindWidget))
    UTextBlock* WeaponNameText;

    UPROPERTY(meta = (BindWidget))
    UTextBlock* AmmoText;

    UPROPERTY(meta = (BindWidget))
    UTextBlock* MaxAmmoText; // 최대 탄약량 텍스트 블록 추가

    UPROPERTY(meta = (BindWidget))
    UTextBlock* HealthText;

    UPROPERTY(meta = (BindWidget))
    UTextBlock* EnemiesRemainingText;

    UPROPERTY(meta = (BindWidget))
    UTextBlock* KillCountText; // 킬카운트 텍스트 블록 추가
};

여기서는 MaxAmmoTextKillCountText라는 텍스트 블록을 새로 선언한다. 각각 최대 탄약량과 킬카운트를 표시한다. UpdateMaxAmmoUpdateKillCount 함수도 추가해서 값을 갱신할 수 있게 만든다.


2. 소스 파일(CP_PlayerHUD.cpp) 수정

다음으로 소스 파일에서 초기값 설정과 업데이트 로직을 넣는다. NativeConstruct에서 텍스트 블록의 기본값을 설정하고, 각 함수에서 값을 업데이트한다.

#include "CP_PlayerHUD.h"
#include "Components/TextBlock.h"

UCP_PlayerHUD::UCP_PlayerHUD(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{
}

void UCP_PlayerHUD::NativeConstruct()
{
    Super::NativeConstruct();
    if (WaveText) WaveText->SetText(FText::AsNumber(0));
    if (WeaponNameText) WeaponNameText->SetText(FText::FromString("No Weapon"));
    if (AmmoText) AmmoText->SetText(FText::AsNumber(0));
    if (MaxAmmoText) MaxAmmoText->SetText(FText::AsNumber(0)); // 최대 탄약량 초기값 설정
    if (HealthText) HealthText->SetText(FText::AsNumber(100));
    if (EnemiesRemainingText) EnemiesRemainingText->SetText(FText::AsNumber(0));
    if (KillCountText) KillCountText->SetText(FText::AsNumber(0)); // 킬카운트 초기값 설정
}

void UCP_PlayerHUD::UpdateWave(int32 Wave)
{
    if (WaveText)
    {
        WaveText->SetText(FText::AsNumber(Wave));
    }
}

void UCP_PlayerHUD::UpdateWeaponName(const FString& WeaponName)
{
    if (WeaponNameText)
    {
        WeaponNameText->SetText(FText::FromString(WeaponName));
    }
}

void UCP_PlayerHUD::UpdateAmmo(int32 Ammo)
{
    if (AmmoText)
    {
        AmmoText->SetText(FText::AsNumber(Ammo));
    }
}

void UCP_PlayerHUD::UpdateMaxAmmo(int32 MaxAmmo)
{
    if (MaxAmmoText)
    {
        MaxAmmoText->SetText(FText::AsNumber(MaxAmmo)); // 최대 탄약량 업데이트
    }
}

void UCP_PlayerHUD::UpdateHealth(int32 Health)
{
    if (HealthText)
    {
        HealthText->SetText(FText::AsNumber(Health));
    }
}

void UCP_PlayerHUD::UpdateEnemiesRemaining(int32 EnemiesRemaining)
{
    if (EnemiesRemainingText)
    {
        EnemiesRemainingText->SetText(FText::AsNumber(EnemiesRemaining));
    }
}

void UCP_PlayerHUD::UpdateKillCount(int32 KillCount)
{
    if (KillCountText)
    {
        KillCountText->SetText(FText::AsNumber(KillCount)); // 킬카운트 업데이트
    }
}

NativeConstruct에서는 HUD가 처음 생성될 때 기본값을 넣는다. 최대 탄약량은 0, 킬카운트도 0으로 시작한다. 각 업데이트 함수는 텍스트 블록이 존재하는지 확인한 뒤 값을 설정한다.


3. 블루프린트에서 작업하기

코드만으로는 HUD가 화면에 안 보인다. Unreal Editor에서 WBP_PlayerHUD를 열고 다음을 한다:

  • TextBlock 두 개를 추가한다.
  • 하나는 MaxAmmoText, 다른 하나는 KillCountText로 이름을 짓는다.
  • HUD 디자인에서 위치를 잡는다. 예를 들어, AmmoText 옆에 MaxAmmoText를 놓고, 킬카운트는 아래쪽에 배치한다.

이렇게 하면 코드와 블루프린트가 연결된다.


4. HUD 업데이트는 어디서?

이 HUD는 외부에서 호출해야 값이 바뀐다. 플레이어 캐릭터나 게임 모드에서 상태가 변할 때마다 함수를 부른다:

  • 무기를 바꾸면 UpdateWeaponNameUpdateMaxAmmo를 호출한다.
  • 탄약을 쓰면 UpdateAmmo를 호출한다.
  • 적을 처치하면 UpdateKillCount를 호출한다.

예를 들어, 플레이어 캐릭터 코드에서:

if (UCP_PlayerHUD* PlayerHUD = Cast<UCP_PlayerHUD>(GetWorld()->GetFirstPlayerController()->GetHUD()))
{
    PlayerHUD->UpdateMaxAmmo(100);
    PlayerHUD->UpdateKillCount(5);
}

마무리

이렇게 하면 HUD에 최대 탄약량과 킬카운트가 추가된다. 기존에 분할된 업데이트 함수 구조도 그대로 유지해서 팀원의 요청도 충족한다. 코드와 블루프린트를 잘 연결하면 게임 중에 플레이어가 필요한 정보를 바로 확인할 수 있다. 간단하지만 필수적인 기능이니, 프로젝트에 따라 더 확장해보는 것도 좋겠다.

0개의 댓글