Dev./UE 언리얼 엔진

[TIL_250214] UI 위젯 설계와 실시간 데이터 연동하기

raindrovvv 2025. 2. 14. 21:18

🗺️마인드맵

📒학습 내용

UI 위젯 설계와 실시간 데이터 연동 📊


WHY – 배운 이유 및 구현 목적

UMG(User Widget)는 언리얼 엔진에서 UI 제작을 위한 강력한 도구이다.
PlayerController에서 HUD를 생성하고, GameState와 연결해 실시간으로 UI를 갱신할 수 있으며, SetText와 Binding 방식을 적절히 활용하면 퍼포먼스 최적화도 가능하다. 정리해보자면...

  • UI 시스템 게임 플레이 경험을 크게 좌우하기 때문에 학습이 필요하다.
  • UMG 시스템을 사용하면 직관적이고 세련된 UI를 제작할 수 있으며, GameState 연동하여 실시간 데이터 표시가 가능하다.
  • SetText 방식과 Binding 방식을 적절히 사용하면 퍼포먼스 최적화 데이터 동기화를 모두 만족할 수 있다.

이번 학습을 통해 UMG 기반 UI 시스템을 제작하고, GameState와 데이터 연동까지 경험할 수 있었다. (앞으로는 애니메이션이 적용된 UI와 ProgressBar 실시간 업데이트를 학습하며, 게임 UI 최적화 기법도 익히고자 한다)


HOW – 학습 및 적용 과정

1. UMG 기초 이해 및 위젯 디자인

  • HUD: 게임 내 체력, 미니맵, 점수 등을 표시하는 화면 요소이다.
  • Canvas 기반 HUDUMG 방식이 있으며, UMGWidget Blueprint를 사용해 텍스트, 버튼, 이미지, Progress Bar 등을 드래그 앤 드롭으로 배치할 수 있다.
  • Widget BlueprintDesigner 탭(UI 배치)과 Graph 탭(UI 로직 작성)으로 구성된다.

📌 문제: 1920x1080 해상도 기준으로 UI를 맞추는 과정에서 요소 배치가 깨지는 문제가 발생했다.
💡 해결 방법: Screen Size 옵션1920x1080으로 맞추고, Anchor를 활용해 해상도 변경에도 UI가 안정되게 표시되도록 수정했다.


2. PlayerController에서 HUD 생성

  • HUDPlayerController에서 CreateWidget 함수를 사용해 생성하고, AddToViewport로 화면에 표시한다.
  • UMG 모듈을 Build.cs에 추가하지 않으면 컴파일 에러가 발생하므로 반드시 추가해야 한다.
#include "Blueprint/UserWidget.h"

void ASP_PlayerController::BeginPlay() {
    Super::BeginPlay();
    if (HUDWidgetClass) {
        UUserWidget* HUDWidget = CreateWidget<UUserWidget>(this, HUDWidgetClass);
        if (HUDWidget) HUDWidget->AddToViewport();
    }
}

📌 문제: UMG 모듈 추가를 잊어 CreateWidget 함수가 작동하지 않았다.
💡 해결 방법: SpartaProject.Build.cs에 "UMG" 모듈을 추가하여 문제를 해결했다.


3. GameState와 UI 데이터 연동

  • GameState에서 점수, 레벨, 타이머 데이터를 관리하며, HUDBinding하거나 SetText로 표시한다.
  • Binding 방식은 UI 자동 갱신이 가능하지만, Tick 함수 호출성능 오버헤드가 발생할 수 있다.
  • SetText 방식은 필요한 순간에만 UI를 업데이트하므로 퍼포먼스에 유리하다.
void AMyGameState::UpdateHUD() {
    if (APlayerController* PC = GetWorld()->GetFirstPlayerController()) {
        if (ASP_PlayerController* SP_PC = Cast<ASP_PlayerController>(PC)) {
            if (UUserWidget* HUD = SP_PC->GetHUDWidget()) {
                if (UTextBlock* ScoreText = Cast<UTextBlock>(HUD->GetWidgetFromName(TEXT("Score")))) {
                    ScoreText->SetText(FText::FromString(FString::Printf(TEXT("Score: %d"), Score)));
                }
            }
        }
    }
}

📌 문제: Binding 방식으로 UI를 업데이트할 때, 프레임 드랍이 발생했다.
💡 해결 방법: SetText 방식으로 전환하고, 0.1초 주기HUD 업데이트 타이머를 설정해 부드럽고 효율적인 갱신을 구현했다.


4. HUD 위젯 갱신 테스트

  • WBP_HUD에서 Text Block정상적으로 갱신되는지 확인하고, PlayerController에서 HUD 업데이트가 잘 이루어지는지 테스트했다.

📌 문제: 게임 실행 후 HUD화면에 표시되지 않는 문제가 발생했다.
💡 해결 방법: Game Mode에서 Default PlayerController를 SP_PlayerController로 지정하지 않았기 때문이었다. 게임 모드 설정을 수정하여 해결했다.


WHAT – 적용 결과 및 산출물

구현 결과

  • UMG 기반 HUD를 제작하고, PlayerController에서 HUD 생성화면 표시를 구현했다.
  • GameStateHUD를 연동해 점수, 타이머, 레벨실시간으로 갱신했다.
  • SetText 방식으로 UI 업데이트 성능을 개선하고, 1920x1080 해상도에 맞춰 UI 최적화를 완료했다.

코드 예시

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HUD")  
TSubclassOf<UUserWidget> HUDWidgetClass;  
  
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HUD")  
UUserWidget* HUDWidgetInstance;  
  
void ASP_PlayerController::BeginPlay() {
    Super::BeginPlay();
    if (HUDWidgetClass) {
        HUDWidgetInstance = CreateWidget<UUserWidget>(this, HUDWidgetClass);
        if (HUDWidgetInstance) HUDWidgetInstance->AddToViewport();
    }
}

🔗 참고 자료


🟣오늘의 옵시디언 현황