Unreal Engine - 간단한 UI 만들기 (HUD)

2025. 2. 12. 20:04·Unreal Engine

1. 기본 세팅


  • 위젯 블루프린트 선택 후 -> 사용자 위젯 선택

  • 디자이너 탭
      • 팔레트 -> 패널 -> 캔버스 패널 추가
      • 추가적으로 아래와 같이 화면 크기를 조절하여, 우리가 구현하고자 하는 게임에 사이즈에 맞는 화면을 세팅할 수 있다.
    • 팔레트 -> 일반 -> 텍스트 추가
      • 아래와 같이 구성해 주었다.
      • 글씨 크기나 폰트, 가운데 정렬 등의 옵션은 디테일 창의 폰트에서 바꿀 수 있다.

 

 

2. 플레이어와 UI 연동


대체로 UI와 캐릭터의 연동은 PlayerController에서 수행한다. 

그 이유는 플레이어의 입력과 상호작용하며, 화면에 표시되는 요소이기 때문이다.

  • PlayerController 세팅
    • UUserWidget 타입의 변수를 하나 선언해주고,
    • 생성자에서 BP를 ConstructorHelpers로 가져와서 연동한 후
    • BeginPlay에서 화면에 보이도록 세팅을 해주면 된다.
    • ConstructorHelpers 로 가져올 때 주의점
      • 경로명 뒤에 _C 를 붙여주어야 한다.
      • FClassFinder로 가져와야 한다.
//playercontroller.h

//새로 추가한 변수
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI")
TSubclassOf<UUserWidget> HUDWidgetClass;

//playercontroller.cpp
#include "Blueprint/UserWidget.h"
	
APlayerCharacterController::APlayerCharacterController()
{
	...	
	static ConstructorHelpers::FClassFinder<UUserWidget>HUDWidget(TEXT("/Game/UI/WBP_HUD.WBP_HUD_C"));
	if (HUDWidget.Succeeded())
	{
		HUDWidgetClass = HUDWidget.Class;
	}	
}
void APlayerCharacterController::BeginPlay()
{
	...
    
	if (HUDWidgetClass)
	{
		UUserWidget* HUDWidget = CreateWidget<UUserWidget>(this, HUDWidgetClass);
		if (HUDWidget)
		{
			HUDWidget->AddToViewport();
		}
	}
}
  • 주의점!
    • 위 코드를 빌드하려면, Build.cs에 UMG 모듈을 추가해주어야 한다.
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "UMG" });
  • 실행 화면 세팅 방법
    • 플레이옵션 -> 고급 세팅 -> 뷰포트 해상도 설정
    • 새 에디터 창으로 플레이

  • 실행 모습
    • 우리가 UI로 구성했던 위치에 Text가 제대로 뜨는 모습을 볼 수 있다.

 

 

3. UI 값 연동


BP에서 Binding을 통해 값을 연동할 수 있지만, 다 효율적인 동작을 위해서 Text Block의 SetText를 호출해서 구현할 것이다.

  • 로직
    • Timer 이벤트를 통해 GameState의 정보를 얻어와
    • HUD 위젯에 있는 TextBlock의 SetText를 호출
    • 우리가 "Text로 작성한 변수값이 변하는 순간" Call 해주기
  • 구현 내용
    • GameState
      • TimerHandle 추가 및 SetTimer 함수를 통해 UpdateHUD 호출
      • UpdateHUD 함수 추가
    • PlayerController
      • UUserWidget* 타입의 WidgetInstance 변수 생성
      • WidgetInstance 리턴하는 함수 추가 (GameState에서 받아와서 사용해야하기 때문에)
  • GameState의 BeginPlay와 UpdateHUD 함수
    • 이 함수를 값이 업데이트 되는 곳에서 Call (BeginPlay, StartLevel, GameOver 등)
    • GameInstance에서 값을 받아와서 Text에 적용하는 로직 존재
void ADefaultGameState::BeginPlay()
{
	Super::BeginPlay();

	UpdateHUD();
	StartLevel();

	//HUD Timer
	GetWorldTimerManager().SetTimer
	(
		HUDUpdateTimerHandle
		,this
		,&ADefaultGameState::UpdateHUD
		,0.1f
		,true
	);
}

void ADefaultGameState::UpdateHUD()
{
	if (APlayerController* PlayerController = GetWorld()->GetFirstPlayerController())
	{
		if (APlayerCharacterController* PlayerCharacterController = Cast<APlayerCharacterController>(PlayerController))
		{
			if (UUserWidget* HUDWidget = PlayerCharacterController->GetHUDWidget())
			{
				//Timer Text
				if (UTextBlock* TimeText = Cast<UTextBlock>(HUDWidget->GetWidgetFromName(TEXT("Time"))))
				{
					float RemainingTime = GetWorldTimerManager().GetTimerRemaining(LevelTimerHandle);
					TimeText->SetText(FText::FromString(FString::Printf(TEXT("Time : %.1f"),RemainingTime)));
				}

				if (UTextBlock* ScoreText = Cast<UTextBlock>(HUDWidget->GetWidgetFromName(TEXT("Score"))))
				{
					if (UGameInstance* GameInstance = GetGameInstance())
					{
						if (UDefaultGameInstance* DefaultGameInstance = Cast<UDefaultGameInstance>(GameInstance))
						{
							ScoreText->SetText(FText::FromString(FString::Printf(TEXT("Score : %d"), DefaultGameInstance->TotalScore)));
						}
					}
				}
				if (UTextBlock* LevelText = Cast<UTextBlock>(HUDWidget->GetWidgetFromName(TEXT("Level"))))
				{
					if (UGameInstance* GameInstance = GetGameInstance())
					{
						if (UDefaultGameInstance* DefaultGameInstance = Cast<UDefaultGameInstance>(GameInstance))
						{
							LevelText->SetText(FText::FromString(FString::Printf(TEXT("Level : %d"), DefaultGameInstance->CurrentLevel + 1)));
						}
					}
				}
			}
		}
	}
}
  • PlayerController의 BeginPlay 함수
void APlayerCharacterController::BeginPlay()
{
	...
	if (HUDWidgetClass)
	{
		HUDWidgetInstance = CreateWidget<UUserWidget>(this, HUDWidgetClass);
		if (HUDWidgetInstance)
		{
			HUDWidgetInstance->AddToViewport();
		}
	}

	ADefaultGameState* DefaultGameState = GetWorld() ? GetWorld()->GetGameState<ADefaultGameState>() : nullptr;
	if (DefaultGameState)
	{
		DefaultGameState->UpdateHUD();
	}
}
  • 실행 모습

 

'Unreal Engine' 카테고리의 다른 글

Unreal Engine - UI Animation  (0) 2025.02.13
Unreal Engine - Main Menu UI (Start, Restart)  (0) 2025.02.12
UE5 Issues : Complex Collision  (0) 2025.02.11
UE5 Issues : Look Action (bUsePawnControlRotation)  (0) 2025.02.11
Unreal Engine - Game Loop  (0) 2025.02.09
'Unreal Engine' 카테고리의 다른 글
  • Unreal Engine - UI Animation
  • Unreal Engine - Main Menu UI (Start, Restart)
  • UE5 Issues : Complex Collision
  • UE5 Issues : Look Action (bUsePawnControlRotation)
gbleem
gbleem
gbleem 님의 블로그 입니다.
  • gbleem
    gbleem 님의 블로그
    gbleem
  • 전체
    오늘
    어제
    • 분류 전체보기 (176)
      • Unreal Engine (66)
      • C++ (19)
      • 알고리즘(코딩테스트) (26)
      • TIL (60)
      • CS (4)
      • 툴 (1)
  • 블로그 메뉴

    • 홈
    • 카테고리
  • 링크

    • 과제용 깃허브
    • 깃허브
    • velog
  • 공지사항

  • 인기 글

  • 태그

    const
    cin함수
    additive animation
    actor 클래스
    BFS
    싱글턴
    character animation
    Vector
    enhanced input system
    gamestate
    motion matching
    blend pose
    매크로 지정자
    C++
    템플릿
    map을 vector로 복사
    DP
    addonscreendebugmessage
    상속
    applydamage
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
gbleem
Unreal Engine - 간단한 UI 만들기 (HUD)
상단으로

티스토리툴바