나만의 작은 도서관

[TIL][C++] 251028 MMO 서버 개발 124일차: [언리얼] ProjectWorldToScreen() 함수 예제, 위젯 컴포넌트를 사용한 경우와 비교했을때 차이점은 무엇일까? 본문

Today I Learn

[TIL][C++] 251028 MMO 서버 개발 124일차: [언리얼] ProjectWorldToScreen() 함수 예제, 위젯 컴포넌트를 사용한 경우와 비교했을때 차이점은 무엇일까?

pledge24 2025. 10. 29. 04:14
주의사항: 해당 글은 일기와 같은 기록용으로, 다듬지 않은 날것 그대로인 글입니다. 

[언리얼] ProjectWorldToScreen() 함수 예제

  • ProjectWorldToScreen은 3D 월드 좌표를 유저가 보는 스크린(뷰포트) 좌표로 변환할 때 사용하는 함수이다.
  • APlayerController에 정의되어 있기 때문에 APlayerController를 끌고 와야 사용할 수 있으며, ProjectWorldToScreen() 함수의 소스 코드는 아래와 같이 되어있다.
bool APlayerController::ProjectWorldLocationToScreen(FVector WorldLocation, FVector2D& ScreenLocation, bool bPlayerViewportRelative) const
{
	return UGameplayStatics::ProjectWorldToScreen(this, WorldLocation, ScreenLocation, bPlayerViewportRelative);
}
  • 단순히 UGameplayStatics의 함수를 호출하는 형태이며, 넘겨받은 매개변수 + 자신이 가지고 있는 데이터로 인자를 넘겨주고 있는 걸 알 수 있다.
  • 추가적으로 설명하자면 ProjectWorldLocationToScreen() 함수는 인자로 넣어준 ScreenLocation에 결과가 저장되고, 리턴값인 bool은 “스크린 상에 표시되는가?”를 의미한다.

 

사용처 및 사용 예제

  • 월드 공간의 특정 지점 위에 HUD 요소를 표시하기 위해 사용한다. 주로 표시하는 HUD 요소는 이름표나 체력 바 등이 있다. 아래 예제는 월드에 배치된 액터의 월드 좌표를 스크린 좌표로 변환하는 예제이다.
#include "Kismet/GameplayStatics.h"

// AMyHUD는 
void AMyHUD::DrawWidgetOnActor(AActor* TargetActor)
{
	APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
	if(PlayerController && TargetActor
	{
		// Actor의 월드 좌표 추출
		FVector WorldPos = TargetActor->GetActorLocation();
		FVector2D ScreenPos;
		
		// ProjectWorldLocationToScreen() 함수 실행
		if(bool bOnScreen = PlayerController->ProjectWorldLocationToScreen(WorldPos, ScreenPos, true))
		{
			// 스크린 상에 위치
		}
		else
		{
			// 스크린 상에 위치 X
		}
	}
}


 

위젯 컴포넌트를 사용한 경우와 비교했을 때 차이점은 무엇일까?

  • 액터에 위젯 컴포넌트를 부착하는 방식으로 액터의 HP바나 이름바를 표시할 수 있다. 이 방식을 사용하면 ProjectWorldLocationToScreen() 함수를 사용하는 경우와 차이점은 무엇일까?
  • 위젯 컴포넌트의 경우 Space 설정을 할 수 있다. Space 설정은 위젯이 표시될 공간을 설정하는 것으로, World와 Screen이 있다. 각각을 적용했을 때 효과는 아래와 같다.

 

Space::World로 적용할 경우

  • 위젯이 월드 공간에 배치된다.
  • BP에서 설정한 Transform 위치가 3D 월드 좌표에 그대로 적용되기 때문에 아래와 같은 특징을 가진다.
    • 벽이나 다른 지형지물 뒤로 이동하면 가려진다.
    • 액터가 카메라에서 멀어지면 작아지고, 가까워지는 커지는, 즉, 원근감이 위젯에 적용된다.
    • 액터의 회전이 위젯에 적용되며, 플레이어가 위젯을 바라보면 회전된 상태의 위젯을 보게 된다. (위젯 컴포넌트의 위젯의 뒷면은 투명해서 위젯 뒤에 있으면 위젯이 보이지 않는다.)

 

Space::Screen으로 적용할 경우

  • 위젯이 Screen 공간에 배치된다.(즉, HUD 공간)
  • BP에서 설정한 Transform에서 Location만 사용되어 스크린에 투영되기 때문에 아래와 같은 특지를 가진다.
    • HUD 공간에 있으므로 월드에 존재하는 오브젝트에 의해 가려지지 않는다.
    • 액터와 카메라와의 거리와 관계없이 위젯은 고정된 크기를 가진다.
    • 액터의 회전이 위젯에 적용되지 않는다.

 

Space 설정 비교 정리

  배치된 공간 지형 지물에 가려지는가? 카메라와의 거리가 크기에 영향을 주는가? 회전값이 존재하는가?
Space::World 3D 월드 좌표 O 거리에 따라 크기 변동 O
Space::Screen 2D 스크린(HUD) X 항상 고정된 크기 X

 

 

그래서 차이점은?

  • Space를 World로 설정하는 경우는 크게 다른 걸 알 수 있으니 제외하고, Space::Screen과 ProjectWorldLocationToScreen() 함수를 사용하는 경우를 비교하자면, 표시되는 결과는 같은 것 같다. 다만, 각 몬스터마다 위젯 컴포넌트를 추가하는 방식은 Draw Cost가 높다고 한다. 그래서 최적화를 위해 위젯 컴포넌트를 부착하는 방식보다 따로 관리하는 것을 선호한다고 한다.
    • 최적화에 대해서 좀 말하자면, 따로 매니저를 두고 Hp바나 이름 바를 관리한다면, 오브젝트 풀링을 활용하기 편하고, 한 번에 관리하기도 쉬워진다.