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 에디터' 모드를 구현하세요. 드래그로 위젯 위치를 조정하고 설정을 저장합니다.