Widget Component로 월드에 UI 배치하기

2025. 2. 7. 16:07·내배캠/Unreal Engine

   

🔎Widget Component란?

UMG(Unreal Motion Graphics)로 만든 위젯(텍스트, 이미지, 버튼 등)을 3D 월드에 렌더링 하게 해주는 컴포넌트이다.
UI는 일반적으로 평면적으로 그려지지만, Widget Component를 사용하면 게임 월드 내에서 특정 위치에 배치할 수 있는 3D 형태의 UI를 생성할 수 있다.
예를 들어 NPC의 머리 위에 "체력 바"나 아이템과의 상호작용 "F" 보이게 하는 등의 작업을 할 수 있다.

언리얼 엔진에서 Widget Component를 사용하면, 월드 내 특정 위치(Actor)에 붙여놓고, 카메라 각도에 따라 회전하거나 크기가 달라지는 연출을 할 수 있다.

 

✅ SetWidgetSpace 함수란?

WidgetComponent가 UI를 월드 공간 혹은 스크린 공간 중 어느 곳에 렌더링 할지를 결정하는 함수이다.
WidgetComponent->SetWidgetSpace(EWidgetSpace::World);  // 월드 공간
WidgetComponent->SetWidgetSpace(EWidgetSpace::Screen); // 스크린 공간

Screen은 평면처럼 나오게 되고, World는 월드 상에 배치된 오브젝트처럼 기울어져 보인다

💻SetWidgetSpace: Screen

  • UI가 화면 공간(Screen Spacce)에 렌더링 된다.
  • 2D HUD UI처럼 화면 위에 고정되며, 카메라의 위치나 방향에 관계없이 항상 같은 위치에서 보이게 된다.
  • 카메라가 어디를 보더라도 UI가 화면에 고정되어 있어 가독성이 좋고 크기나 왜곡 걱정 없이 일정한 크기로 표시
  • 월드 내의 오브젝트와 자연스럽게 어우러지지 않으며, 물리적 상호작용이 어렵다.

🌍SetWidgetSpace: World

  • 월드 좌표를 기반으로 위젯 배치
  • UI가 3D 오브젝트처럼 월드 내에서 특정 위치와 회전 값을 가지며, 카메라의 이동에 따라 UI의 시각적 변화
  • 충돌 처리도 가능하여 물리적 상호작용이 필요한 UI에서 사용될 수 있다.
  • 월드 내 특정 위치에 고정된 UI 설계에 적합
  • 카메라에서 멀어지거나 특정 각도에서 왜곡되어 가독성이 좋지 않을 수 있어, 추가적인 작업이 필요할 수 있다.

 


 

📌 캐릭터 메시에 부착할 WBP_HP 만들기

  • TextBlock 생성
  • 글자 크기 설정 및 가운데 정렬

 

📌 캐릭터 클래스에 Widget Component 부착

✅ PlayerCharacter.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "PlayerCharacter.generated.h"

class USpringArmComponent;
class UCameraComponent;
class USphereComponent;
class UWidgetComponent;

UCLASS()
class STRIKEZONE_API APlayerCharacter : public ACharacter
{
	GENERATED_BODY()

public:
	APlayerCharacter();
    
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
	TObjectPtr<USpringArmComponent> SpringArm;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
	TObjectPtr<UCameraComponent> ThirdPersonCamera;
    
    // WidgetComponent 추가
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI")
	TObjectPtr<UWidgetComponent> OverheadWidget;

	UFUNCTION(BlueprintPure, Category = "Health")
	float GetHealth() const { return Health; }
	UFUNCTION(BlueprintPure, Category = "Health")
	float GetMaxHealth() const { return MaxHealth; }
	UFUNCTION(BlueprintCallable, Category = "Health")
	void AddHealth(float Amount);


protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Health")
	float MaxHealth;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Health")
	float Health;

	void OnDeath();
    
    // 체력 UI 업데이트 함수
	void UpdateOverheadHP();

	virtual float TakeDamage(
		float DamageAmount,
		struct FDamageEvent const& DamageEvent,
		AController* EventInstigator,
		AActor* DamageCauser) override;
	virtual void BeginPlay() override;
};
  • UWidgetComponent 선언
  • UpdateOverheadHP(): 체력 업데이트해 UI에 반영

 

✅ PlayerCharacter.cpp

APlayerCharacter::APlayerCharacter()
{
	PrimaryActorTick.bCanEverTick = false;

	OverheadWidget = CreateDefaultSubobject<UWidgetComponent>(TEXT("OverheadWidget"));
	OverheadWidget->SetupAttachment(GetMesh());
	OverheadWidget->SetWidgetSpace(EWidgetSpace::Screen);
}


void APlayerCharacter::UpdateOverheadHP()
{
	if (!OverheadWidget) return;

	UUserWidget* OverheadWidgetInstance = OverheadWidget->GetUserWidgetObject();
	if (!OverheadWidgetInstance) return;

	if (UTextBlock* HPText = Cast<UTextBlock>(OverheadWidgetInstance->GetWidgetFromName("OverheadHP")))
	{
		HPText->SetText(FText::FromString(FString::Printf(TEXT("%.0f / %.0f"), Health, MaxHealth)));
	}
}
  • UWidgetComponent::GetUserWidgetObject() 함수로 위젯 객체의 인스턴스를 반환 받는다.
  • UUserWidget::GetWidgetFormName() 함수로 UTextBlock을 캐스팅
  • SetText()로 현재 체력과 최대 체력 데이터를 반영한 텍스트로 설정
  • UpdateOverheadHP() 함수를 게임이 시작될 때, 데미지를 입었을 때, 체력 회복할 때 등 체력이 변동되는 시점에 호출

 

🔎UWidgetComponent:::GetUserWidgetObject()

Widget Component가 월드에 실제로 렌더링하고 있는 Widget 객체의 Instance를 반환한다.
이 Instance는 UUserWidget 클래스를 기반으로 생성된 객체이며, UI의 실제 동작과 데이터를 포함하고 있다.

 

 

✅ BP_PlayerCharacter

  • Widget Class를 앞서 만들었던 WBP_HP로 설정
  • Space를 Wolrd로 변경하면 Viewport에서 TextBlock이 나타나고 위치를 알맞게 조절

 


 

🔔 결과

왼쪽이 Screen Space, 오른쪽이 World Space

'내배캠 > Unreal Engine' 카테고리의 다른 글

동적 멀티캐스트 델리게이트 (Dynamic Multicast Delegate)  (0) 2025.02.11
Particle과 Sound 효과 연출  (0) 2025.02.07
UI 애니메이션 효과 만들기  (0) 2025.02.07
게임 메뉴 UI 디자인 / 게임 흐름에 맞게 UI 전환  (0) 2025.02.06
UI 위젯 설계와 실시간 데이터 연동  (0) 2025.02.06
'내배캠/Unreal Engine' 카테고리의 다른 글
  • 동적 멀티캐스트 델리게이트 (Dynamic Multicast Delegate)
  • Particle과 Sound 효과 연출
  • UI 애니메이션 효과 만들기
  • 게임 메뉴 UI 디자인 / 게임 흐름에 맞게 UI 전환
동그래님
동그래님
  • 동그래님
    개발자 동그래
    동그래님
  • 전체
    오늘
    어제
    • 분류 전체보기 (210) N
      • 공부 (51)
        • Code Cata (50)
      • 내배캠 (151) N
        • TIL (50)
        • C++ (37)
        • Unreal Engine (48)
        • GAS(Gameplay Ability System.. (16) N
      • Project (7)
        • Gunfire Paragon (5)
        • Arena Fighters (1)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    동그래님
    Widget Component로 월드에 UI 배치하기
    상단으로

    티스토리툴바