PART 6 · 강의 2/3
HUD 시스템
AHUD 클래스, HUD 레이어 관리, 동적 HUD 요소, 크로스헤어 구현을 학습합니다.
01
AHUD vs UMG HUD
레거시 AHUD와 UMG 기반 HUD 비교
AHUD (레거시)
- - Canvas 기반 직접 드로잉
- - DrawText, DrawRect 등 사용
- - 디버그 정보 표시에 적합
- - 상호작용 UI에 부적합
UMG HUD (권장)
- - UUserWidget 기반
- - 에디터에서 시각적 편집
- - 상호작용 및 애니메이션 지원
- - CommonUI 연동 가능
C++ - UMG 기반 HUD 매니저
UCLASS()
class UHUDManager : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
// HUD 레이어 정의
enum class EHUDLayer : uint8
{
Background = 0, // 배경 효과
GameInfo = 10, // HP, 미니맵, 스태미나
Crosshair = 20, // 크로스헤어
Indicator = 30, // 데미지 인디케이터
Overlay = 50, // 전체 화면 오버레이
Debug = 100, // 디버그 정보
};
template<typename T>
T* AddHUDWidget(APlayerController* PC,
TSubclassOf<T> WidgetClass,
EHUDLayer Layer)
{
T* Widget = CreateWidget<T>(PC, WidgetClass);
Widget->AddToViewport((int32)Layer);
ActiveWidgets.Add(Widget);
return Widget;
}
void RemoveAllHUD()
{
for (auto* Widget : ActiveWidgets)
{
if (Widget) Widget->RemoveFromParent();
}
ActiveWidgets.Empty();
}
private:
TArray<UUserWidget*> ActiveWidgets;
};
02
동적 HUD 요소
데미지 넘버, 히트 인디케이터 등 동적 UI
C++ - 플로팅 데미지 넘버
UCLASS()
class UDamageNumberWidget : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(meta = (BindWidget))
UTextBlock* DamageText;
UPROPERTY(Transient, meta = (BindWidgetAnim))
UWidgetAnimation* FloatUpAnimation;
void PlayDamageNumber(int32 Damage, bool bCritical)
{
DamageText->SetText(FText::AsNumber(Damage));
DamageText->SetColorAndOpacity(
bCritical ? FSlateColor(FLinearColor::Yellow)
: FSlateColor(FLinearColor::White));
// UMG 애니메이션 재생 (위로 떠오르며 페이드 아웃)
PlayAnimation(FloatUpAnimation);
// 애니메이션 완료 후 자동 제거
FTimerHandle Handle;
GetWorld()->GetTimerManager().SetTimer(Handle,
[this]() { RemoveFromParent(); },
FloatUpAnimation->GetEndTime(), false);
}
};
// 월드 위치를 화면 좌표로 변환하여 배치
void UGameHUD::SpawnDamageNumber(FVector WorldPos,
int32 Damage, bool bCrit)
{
FVector2D ScreenPos;
if (GetOwningPlayer()->ProjectWorldLocationToScreen(
WorldPos, ScreenPos))
{
auto* DmgWidget = CreateWidget<UDamageNumberWidget>(
GetOwningPlayer(), DamageNumberClass);
DmgWidget->AddToViewport(50);
DmgWidget->SetPositionInViewport(ScreenPos);
DmgWidget->PlayDamageNumber(Damage, bCrit);
}
}
03
크로스헤어 구현
동적 크로스헤어와 히트마커
C++ - 동적 크로스헤어
UCLASS()
class UCrosshairWidget : public UUserWidget
{
GENERATED_BODY()
public:
// 크로스헤어 이미지 (4방향 + 중앙점)
UPROPERTY(meta = (BindWidget)) UImage* TopLine;
UPROPERTY(meta = (BindWidget)) UImage* BottomLine;
UPROPERTY(meta = (BindWidget)) UImage* LeftLine;
UPROPERTY(meta = (BindWidget)) UImage* RightLine;
UPROPERTY(meta = (BindWidget)) UImage* HitMarker;
// 스프레드에 따른 크로스헤어 확장
void UpdateSpread(float SpreadAngle)
{
float Offset = SpreadAngle * SpreadMultiplier;
// 캔버스 슬롯 위치 조정으로 간격 조절
auto* TopSlot = Cast<UCanvasPanelSlot>(TopLine->Slot);
TopSlot->SetPosition(FVector2D(0.f, -Offset));
auto* BottomSlot = Cast<UCanvasPanelSlot>(BottomLine->Slot);
BottomSlot->SetPosition(FVector2D(0.f, Offset));
// Left, Right도 동일하게...
}
// 히트마커 표시
void ShowHitMarker(bool bHeadshot)
{
HitMarker->SetColorAndOpacity(
bHeadshot ? FLinearColor::Red : FLinearColor::White);
HitMarker->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
PlayAnimation(HitMarkerFadeAnim);
}
private:
float SpreadMultiplier = 5.0f;
};
04
CommonUI 레이어 기반 HUD
CommonUI의 레이어 시스템으로 HUD를 관리하는 패턴
C++ - CommonUI 레이어 기반 HUD
// Game UI Layout에서 HUD를 Game Layer로 관리
// (Part 2-3에서 다룬 레이어 구조 활용)
void AMyPlayerController::SetupHUD()
{
// Game Layer에 HUD 위젯 Push
// ECommonInputMode::All로 설정되어 게임 입력 통과
GameUILayout->PushToGameLayer(MainHUDClass);
}
// 인벤토리 열기 → Menu Layer에 Push
// 게임 입력 자동 차단, HUD는 계속 표시
void AMyPlayerController::OpenInventory()
{
GameUILayout->PushToMenuLayer(InventoryClass);
}
SUMMARY
핵심 요약
- UMG 기반 HUD가 레거시
AHUD보다 기능이 풍부하며, CommonUI 연동이 가능합니다 - HUD 레이어(Background, GameInfo, Crosshair, Overlay 등)로 Z-Order를 체계적으로 관리합니다
- 플로팅 데미지 넘버는 월드 좌표를 화면 좌표로 투영하여 위치를 결정합니다
- 동적 크로스헤어는 스프레드 값에 따라 캔버스 슬롯 위치를 조절하여 구현합니다
PRACTICE
도전 과제
배운 내용을 직접 실습해보세요
실습 1: UMG 기반 HUD 레이어 시스템
PlayerController에서 HUD Widget을 생성하고, CanvasPanel 기반으로 HP바(상단 좌측), 미니맵(상단 우측), 스킬바(하단 중앙), 크로스헤어(화면 중앙) 레이아웃을 구성하세요.
실습 2: 동적 HUD 요소 관리
데미지 숫자 팝업, 퀘스트 알림 토스트, 화면 효과(피격 시 비네팅)를 동적으로 생성/제거하는 시스템을 구현하세요. 위젯 애니메이션(UWidgetAnimation)을 활용합니다.
심화 과제
게임 상태(탐색/전투/대화/컷신)에 따라 HUD 요소를 자동으로 표시/숨김하고, 사용자가 HUD 레이아웃을 편집할 수 있는 'HUD 에디터' 모드를 구현하세요. 드래그로 위젯 위치를 조정하고 설정을 저장합니다.