🔎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); // 스크린 공간
💻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 |