PART 1 · 강의 3/3

기본 위젯 활용

TextBlock, Image, Button, ProgressBar 등 UMG의 핵심 리프 위젯을 C++과 블루프린트에서 효과적으로 사용하는 방법을 학습합니다.

01

TextBlock과 RichTextBlock

텍스트 표시의 기본과 서식 지정

UTextBlock은 단일 스타일의 텍스트를 표시하는 가장 기본적인 위젯이고, URichTextBlock은 인라인 마크업으로 여러 스타일을 혼합할 수 있는 고급 텍스트 위젯입니다.

C++ - TextBlock 제어
// .h 파일 - BindWidget으로 블루프린트 위젯 참조 UPROPERTY(meta = (BindWidget)) UTextBlock* PlayerNameText; UPROPERTY(meta = (BindWidget)) UTextBlock* ScoreText; // .cpp 파일 - 텍스트 설정 void UMyHUD::UpdatePlayerInfo(const FString& Name, int32 Score) { PlayerNameText->SetText(FText::FromString(Name)); // FText::Format으로 로컬라이제이션 지원 포맷팅 ScoreText->SetText(FText::Format( NSLOCTEXT("HUD", "ScoreFormat", "점수: {0}"), FText::AsNumber(Score) )); // 폰트 크기 동적 변경 FSlateFontInfo FontInfo = ScoreText->GetFont(); FontInfo.Size = 24; ScoreText->SetFont(FontInfo); // 색상 변경 ScoreText->SetColorAndOpacity(FSlateColor(FLinearColor::Yellow)); }
BindWidget 메타 태그

meta = (BindWidget)은 블루프린트 Widget Blueprint에서 같은 이름의 위젯을 자동으로 바인딩합니다. 위젯 이름이 일치하지 않으면 컴파일 에러가 발생합니다. 선택적 바인딩은 meta = (BindWidgetOptional)을 사용하세요.

RichTextBlock - 인라인 스타일

RichTextBlock 마크업 예시
// Data Table 기반 스타일 시트 + 마크업 // "Default", "Bold", "Damage" 등의 행을 가진 DataTable 필요 // 블루프린트에서 RichTextBlock 텍스트 설정: "적에게 <Bold>치명타</> <Damage>1,500</> 데미지!" // C++에서 설정: RichText->SetText(FText::FromString( "적에게 <Bold>치명타</> <Damage>1,500</> 데미지!" ));
02

Image 위젯

텍스처, 머티리얼, 브러시를 활용한 이미지 표시

UImage 위젯은 텍스처, 머티리얼 인스턴스, 또는 Slate 브러시를 화면에 렌더링합니다. 게임 UI에서 아이콘, 배경, 장식 요소 등에 광범위하게 사용됩니다.

C++ - Image 위젯 다양한 사용법
UPROPERTY(meta = (BindWidget)) UImage* IconImage; void UItemSlot::SetItemIcon(UTexture2D* Texture) { if (Texture) { // 텍스처를 브러시로 설정 IconImage->SetBrushFromTexture(Texture); // 브러시 크기 지정 IconImage->SetDesiredSizeOverride(FVector2D(64.f, 64.f)); } } void UItemSlot::SetRarityBorder(UMaterialInterface* RarityMat) { // 머티리얼 인스턴스를 이미지 브러시로 사용 IconImage->SetBrushFromMaterial(RarityMat); } void UItemSlot::SetTintColor(FLinearColor Color) { // 브러시 틴트 컬러 변경 IconImage->SetColorAndOpacity(Color); } void UItemSlot::SetFromSlateBrush() { // 코드에서 직접 브러시 구성 FSlateBrush Brush; Brush.ImageSize = FVector2D(64.f, 64.f); Brush.TintColor = FSlateColor(FLinearColor::White); Brush.DrawAs = ESlateBrushDrawType::Image; IconImage->SetBrush(Brush); }
머티리얼 기반 이미지 애니메이션

Image 위젯에 Dynamic Material Instance를 설정하면 셰이더 파라미터를 조작하여 GPU 기반 애니메이션을 만들 수 있습니다. 글로우 효과, 스크롤링 배경, 디졸브 전환 등에 활용하면 CPU 비용 없이 시각 효과를 구현할 수 있습니다.

03

Button과 상호작용 위젯

버튼 클릭, 체크박스, 슬라이더 이벤트 처리

C++ - Button 이벤트 바인딩
// .h 파일 UPROPERTY(meta = (BindWidget)) UButton* StartButton; UPROPERTY(meta = (BindWidget)) UButton* SettingsButton; UFUNCTION() void OnStartClicked(); UFUNCTION() void OnSettingsHovered(); // .cpp 파일 - NativeConstruct에서 바인딩 void UMainMenu::NativeConstruct() { Super::NativeConstruct(); // 클릭 이벤트 바인딩 StartButton->OnClicked.AddDynamic(this, &UMainMenu::OnStartClicked); // 호버 이벤트 바인딩 SettingsButton->OnHovered.AddDynamic(this, &UMainMenu::OnSettingsHovered); } void UMainMenu::OnStartClicked() { // 버튼 스타일 변경 FButtonStyle Style = StartButton->GetStyle(); Style.Normal.TintColor = FSlateColor(FLinearColor::Green); StartButton->SetStyle(Style); // 게임 시작 로직 GetWorld()->ServerTravel("/Game/Maps/GameLevel"); }

CheckBox와 Slider

C++ - CheckBox & Slider
UPROPERTY(meta = (BindWidget)) UCheckBox* VSyncCheckBox; UPROPERTY(meta = (BindWidget)) USlider* VolumeSlider; void USettingsWidget::NativeConstruct() { Super::NativeConstruct(); // CheckBox 상태 변경 이벤트 VSyncCheckBox->OnCheckStateChanged.AddDynamic( this, &USettingsWidget::OnVSyncChanged); // Slider 값 변경 이벤트 VolumeSlider->OnValueChanged.AddDynamic( this, &USettingsWidget::OnVolumeChanged); // 초기값 설정 VolumeSlider->SetValue(0.8f); VolumeSlider->SetMinValue(0.0f); VolumeSlider->SetMaxValue(1.0f); } void USettingsWidget::OnVSyncChanged(bool bIsChecked) { // CVar로 VSync 설정 변경 auto* Settings = GEngine->GetGameUserSettings(); Settings->SetVSyncEnabled(bIsChecked); Settings->ApplySettings(false); } void USettingsWidget::OnVolumeChanged(float Value) { // Sound Mix를 통한 볼륨 조절 USoundMix* MasterMix = /* Sound Mix 에셋 참조 */; UGameplayStatics::SetSoundMixClassOverride( this, MasterMix, MasterSoundClass, Value, 1.0f, 0.1f); }
04

ProgressBar와 동적 UI

게이지, 로딩바, 쿨다운 등 동적 피드백 위젯

C++ - ProgressBar 활용
UPROPERTY(meta = (BindWidget)) UProgressBar* HealthBar; UPROPERTY(meta = (BindWidget)) UProgressBar* CooldownBar; void UGameHUD::UpdateHealth(float Current, float Max) { float Percent = (Max > 0.f) ? Current / Max : 0.f; HealthBar->SetPercent(Percent); // HP에 따른 색상 변경 FLinearColor BarColor; if (Percent > 0.5f) BarColor = FLinearColor::Green; else if (Percent > 0.25f) BarColor = FLinearColor(1.f, 0.5f, 0.f); // 주황 else BarColor = FLinearColor::Red; HealthBar->SetFillColorAndOpacity(BarColor); } // 쿨다운 바: 타이머 기반 업데이트 void UGameHUD::StartCooldown(float Duration) { CooldownDuration = Duration; CooldownRemaining = Duration; bCooldownActive = true; } void UGameHUD::NativeTick(const FGeometry& Geometry, float DeltaTime) { Super::NativeTick(Geometry, DeltaTime); if (bCooldownActive) { CooldownRemaining -= DeltaTime; float Pct = FMath::Clamp(CooldownRemaining / CooldownDuration, 0.f, 1.f); CooldownBar->SetPercent(Pct); if (CooldownRemaining <= 0.f) bCooldownActive = false; } }
Tick 사용 주의

NativeTick()은 매 프레임 호출되므로 성능에 영향을 줍니다. 쿨다운처럼 지속적인 업데이트가 필요한 경우에만 사용하고, HP 변경처럼 이벤트 기반으로 처리 가능한 경우에는 델리게이트/이벤트 디스패처를 통해 필요한 시점에만 업데이트하세요.

Tick 기반 (비효율적)

// 매 프레임 체크 - 불필요한 비용 void NativeTick(...) { float HP = Character->GetHP(); HealthBar->SetPercent(HP / MaxHP); }

이벤트 기반 (효율적)

// HP 변경 시에만 업데이트 Character->OnHPChanged.AddDynamic( this, &UGameHUD::UpdateHealth );
SUMMARY

핵심 요약

  • meta = (BindWidget)으로 C++ 코드에서 블루프린트 위젯을 안전하게 참조할 수 있습니다
  • TextBlockFText::Format으로 로컬라이제이션을 지원하고, RichTextBlock은 인라인 마크업으로 복합 스타일을 적용합니다
  • Image 위젯은 텍스처, 머티리얼, Slate 브러시를 모두 지원하며 Dynamic Material Instance로 GPU 애니메이션이 가능합니다
  • Button의 OnClicked/OnHovered 델리게이트에 바인딩하여 상호작용을 처리합니다
  • 지속적 업데이트에는 Tick을, 상태 변경에는 델리게이트/이벤트 기반 패턴을 사용하여 성능을 최적화합니다
PRACTICE

도전 과제

배운 내용을 직접 실습해보세요

실습 1: RichTextBlock 스타일 시트 구성

DataTable 기반 RichTextBlock 스타일 시트를 만들고, <bold>, <highlight>, <damage> 등의 커스텀 태그로 게임 내 대화 텍스트를 다양하게 꾸며 보세요. 인라인 이미지(아이템 아이콘)도 추가합니다.

실습 2: ProgressBar 커스터마이징

UProgressBar의 FillImage를 커스텀 머티리얼로 교체하고, C++에서 SetPercent()와 SetFillColorAndOpacity()를 사용하여 HP가 낮아질수록 색상이 변하는 체력바를 구현해 보세요.

심화 과제

TextBlock + Image + ProgressBar를 조합한 '스킬 슬롯' UserWidget을 만들고, 쿨다운 표시(원형 와이프), 스킬 레벨 텍스트, 아이콘을 모두 포함하는 재사용 가능한 컴포넌트를 완성하세요.