UE4에서의 UI를 구성하기 위한 프레임워크
- UMG(Unreal Motion Graphic)
- HUD(Head Up Display)
- Sloat Framework
UI(User Inteface)란?
유저 인터페이스는 메뉴와 상호작용형 요소를 말합니다. 이러한 요소는 보통 HUD와 매우 흡사하게 화면상에서 그려지지만, 특정 상황에서는 월드의 표면위에 랜더링되는 게임 월드 자체의 일부가 되기도 합니다. UI의 가장 명확한 예는 게임 시작시 표시되는 메인 메뉴나, 플레이어가 게임을 일시정지시킬 때 뜨는 메뉴입니다. 그 외에도 플레이 도중 다른 UI가 표시 될 수도 있습니다. 이를 통해 게임 내 캐릭터간의 대화를 표시할 수도 있고, RTS나 RPG처럼 좀 더 복잡한 상황에서는 플레이어의 무기, 갑옷, 빌드할 유닛 등의 선택을 위한 게임플레이 핵심 요소가 될 수도 있습니다.
UMG(Unreal Motion Graphic)
UMG는 현재 언리얼 엔진4에서 가장 광범위하게 쓰이는 UI 제작 툴이라고 할 수 있습니다. 언리얼 엔진에서는 다음과 같이 정의하고 있습니다.
언리얼 모션 그래픽 UI 디자이너(UMG)는 게임내 HUD, 메뉴, 기타 인퍼테이스 관련 그래픽 요소를 사용자에게 보여주고픈 것들을 만드는 데 사용할 수 있는 비주얼 UI 제작 툴입니다. UMG의 핵심에는 Widget(위젯)이라는 것이 있는데, 이는 미리 만들어진 (버튼, 체크박스, 슬라이더, 진행상황 바 등의) 함수 시리즈로, 이들을 조립해서 UI를 만들 수 있습니다. 이러한 위젯은 전용 Widget Blueprint(위젯 블루프린트)에서 편집되는데, 두 가지 탭으로 구성됩니다. 디자이너 탱벵서는 인터페이스의 시각적인 레이아웃과 기본적인 함수가 제공되며, 그래프 탭에는 사용된 위젯 내부의 함수 기능을 제공합니다.
UMG UI 디자이너 사용 안내서를 통해, 각 그래픽 요소들에 대한 정보 및 사용법을 확인할 수 있으며, 상당히 광범위한 범위의 주제가 공식 문서에 실려있지만, Unity 만큼이나 쉽게 배울 수 있고 각종 레퍼런스들이 많으므로 여기서 이것들에 대한 사용법 등에 대해서는 따로 언급하지 않겠습니다.
HUD(Head Up Display)
HUD는 흔히 아이언맨의 디스플레이나 전투기의 디스플레이 등을 지칭하는 용어입니다. 언리얼 엔진의 공식 문서에 따르면 다음과 같이 정의되어 있습니다.
HUD는 게임플레이 도중 화면 위에 겹쳐놓이는 계기판이나 정보를 가리킵니다. HUD의 목적은 플레이어에게 점수, 생명력, 남은 시간 등 게임의 현재 상태를 알리는 것입니다. HUD는 보통 상호작용적이지 않습니다. 즉 플레이어는 HUD 요소를 클릭할 수 없다는 뜻으로, 어떤 게임 유형에서는 이 부분이 회색으로 변해 HUD와 UI의 구분이 힘들어지기는 합니다.
즉, HUD의 요점은 상호작용이 불가능한 UI 정도로 요약할 수 있겠습니다(HitBox를 통해서 Click 관련 상호작용을 수행할 수는 있습니다.) UE4에서는 UI 구성을 위해서 UMG를 활용하는 것이 일반적이고 많은 사람들 사이에서 권장되는데 HUD 클래스가 존재하는 이유는 레거시(legacy) 호환을 위해서 입니다.
HUD 클래스(클래스의 정확한 명칭은 AHUD)는 UE3 및 UDK(Unreal Development Kit)부터 존재했으며, UE4에서 UMG가 만들어지고 대체되기 전까지 사용되어 왔습니다. 현재로써는 대부분의 역할을 UMG가 대체하였고, HUD보다 훨씬 많은 장점을 지니고 있지만(예를 들어, 화면 스케일링에 따른 DPI Scaling등.), HUD만의 장점을 지니고 있어 어떤 이유로 HUD 클래스를 사용하고자 한다면 사용할 수 있습니다.
또한 HUD는 후술할 UMG와는 독립적으로 수행되는 UI이므로, HUD를 사용하지 않는다고 UMG 위젯이 더 이상 디스플레이되거나 하지는 않습니다.
HUD : 사용
HUD 클래스를 상속하여(C++이든, Blueprint든) 사용자 정의 클래스를 만든 이후 사용하기 위해서는 GameMode에 HUD를 멤버 변수로써 가지고 있는데, GameMode에서 PlayerController 클래스에 HUD Class를 전달하여 설정하도록 하는 것 같습니다.
HUD의 기능을 HUD 클래스 외부에서 사용하고자 할 경우, PlayerController의 GetHud() 함수를 사용하면 해당 플레이어 컨트롤러에 대한 HUD를 취득할 수 있습니다.
이벤트
- ReceiveDrawHUD
- HitBoxBeginCursor
- HitBoxEndCursor
- HitBoxClicked
- HitBoxReleased
HUD는 매 프레임마다 ReceiveDrawHUD라는 이벤트를 호출하는 특징을 갖고 있습니다. 이것은 또다른 매 플에ㅣㅁ마다 호출되는 Tick 함수와는 별개로 호출되는 함수이며, 사용자는 이 이벤트를 통해서 HUD를 제어할 수 있습니다. Tick과 마찬가지로 호출 여부를 제어할 수 있습니다.(SetShowHUD).
나머지 이벤트들은 함수 이름만으로 직관적으로 이해할 수 있으므로 자세한 설명은 언리얼 공식 문서를 통해 찾아보시길 바랍니다.
기능
- ShowDebugInfo
- ShowHitBoxDebugInfo
- ShowOverlays
- DrawTest
DebugInfo는 HUD의 Owner와 Owner의 Location, Rotation등에 대한 정보를 기술합니다.
ShowHitBoxDebugInfo는 HUD의 HitBox에 대한 정보를 기술합니다.
ShowOverlays는 HUD에 Overlay하는 항목(stuff)들을 보여줍니다(BP에서는 사용할 수 없습니다).
Draw 관련 함수들은 위치를 지정할 때 좌상단 기준으로 0.0을 지정하는 것 이외에 필요한 부분은 언리얼 공식 문서를 찾아보시길 바랍니다.
Slate
Slate는 UE4에서 제공되는 UI 프레임워크로 언리얼 공식 문서에서 다음과 같이 정의되어 있습니다.
Slate는 언리얼 엔진4와 함께 제공되는 플랫폼 무관, 완벽한 커스텀 유저 인터페이스 프레임워크로, 언리얼 에디터와 같은 툴과 어플리케이션에 쓸 유저 인터페이스나 게임내 유저 인터페이스의 재미와 효율을 높일 수 있도록 디자인된 것입니다. 서술형(declarative) 문법에 쉬운 디자인, 레이아웃, 스타일 요소가 결합된 Slate를 통해 쉬운 UI 제작 및 반복작업이 가능할 것입니다.
플랫폼 무관(independent), 서술형 등 복잡한 용어들이 많이 나옵니다. 여기서 주목할 것은 서술형 문법 (플랫폼 무관 역시 중요하지만, 애초에 UE4가 플랫폼 무관 엔진이라는 것을 감안하면 그 특징의 세부 요소 중 하나로 보는 것이 맞다고 생각해서 제외했습니다.) 입니다.
서술형 문법이 뭔가? 싶을 수도 있는데 아래 코드 블록을 보시면 감이 오실 거라 믿습니다.
void SStandardSlateWidget::Construct(const FArguments& InArgs)
{
// ++ Asign the argument to our local variable
// name will be _OwnerHUDArg instead of OwnerHUDArg, see comments about SLATE_ARGUMENT before
OwnerHUD = InArgs._OwnerHUDArg;
// ++ Add all this Slate code
// If the code below doesn't look like C++ to you it's because it (sort-of) isn't,
// Slate makes extensive use of the C++ Prerocessor(macros) and operator overloading,
// Epic is trying to make our lives easier, look-up the macro/operator definitions to see why.
/* 여기서부터 서술형 문법입니다 */
ChildSlot
.VAlign(VAlign_Fill)
.HAlign(HAlign_Fill)
[
SNew(SOverlay)
+ SOverlay::Slot()
.VAlign(VAlign_Top)
.HAlign(HAlign_Center)
[
// Inside lies a text block with these settings
SNew(STextBlock)
.ShadowColorAndOpacity(FLinearColor::Black)
.ColorAndOpacity(FLinearColor::Red)
.ShadowOffset(FIntPoint(-1, 1))
.Font(FSlateFontInfo("Veranda", 16))
// localized text to be translated with a generic name HelloSlateText
.Text(LOCTEXT("HelloSlateText", "Hello, Slate!"))
]
];
간략이 설명하자면, 코드를 짠다는 느김 보다는 XML이나 json 마냥 key = value 느낌과 비슷합니다. 이러한 코드의 작성을 통해 특정 UI 컴포넌트의 속성을 빠르게 지정하고 표시할 수 있는 것이 Slate의 핵심입니다.
HUD와 UMG UI, 그리고 Slate
앞에서 HUD와 UMG UI, Slate 프레임워크까지 간단하게 살펴보았습니다. 각각에 대한 자세한 내용까지 기술하면 너무 글이 길어지므로, 추후 포스팅에서 다룰 기회가 있을 때 좀 더 자세히 다루도록하고, 언리얼 공식 문서를 읽어주시길 바랍니다.
한 엔진에 UI를 그릴 수 있는 툴이 3개나 있다는 것은 어떤 의미에서는 사용자 취향을 고려했다고 볼 수 있지만, 넓어진 선택의 기회만큼 알아야 할 것도 많은것이 문제입니다. 따라서 이것에 대한 각각의 비교를 해보겠습니다.
Slate vs UMG
Slate는 서술형 문법을 이용하여 UI를 구성할 수 있으며 UMG는 시각적으로 UI를 구성할 수 있는 점이 가장 큰 차이점입니다. 하지만, 둘은 근본적으로 같은 기술을 사용하고 있습니다. UMG의 구성을 엔진을 통해서 살펴보면 Slate의 기능을 사용하고 있음을 알 수 있습니다.
UMG는 UWidget으로부터 파생되며, UWidget은 엄밀히 말하자면, Slate 모듈을 Unreal 환경에 맞게 래핑(Wrapping)한 것으로 보시면 됩니다.(UWidget에 대한 API를 보시면 멤버 변수로 TWeakPtr을 가지고 있음을 알 수 있습니다.) 즉, 내부적으로 Slate 모듈의 기능을 사용한다고 보시면 되겠습니다. Slate는 SWidget으로부터 파생되며, Slate 관련 항목에 사용됩니다.
HUD vs UMG(Slate)
일반적으로 HUD는 구식으로, UMG는 최신으로 여겨져 많은 사람들이 UMG의 사용을 권장합니다. HUD 클래스는 단지 legacy로써 존재하는 걸까요? 사용자 측면에서 바라봤을 때 HUD는 간단하게 프로토타이핑 하기에 좋고, UMG는 HUD의 상위 집합으로 볼 수 있습니다. 하지만, 기술적인(코드의 구성 차이에 따른) 측면에서 보았을 때, 네트워킹 등의 차이점이 있다고 합니다.
이 포럼에서 HUD의 존재 이유에 대한 많은 탐구와 답변들이 있으니 살펴보시길 바랍니다. 또한 이 포럼에서 HUD와 Widget의 관계에 대한 주제로 논의되어 있으니 살펴보면 좋을것 같습니다.
'DevLog > Unreal Engine' 카테고리의 다른 글
언리얼엔진4 게임플레이 파이프라인 (0) | 2021.03.01 |
---|---|
언리얼 엔진4 모바일 렌더링, 이것만 기억하세요 (0) | 2021.02.05 |
[UE4 게임플레이 프레임 워크] 게임 모드와 게임 스테이트 (0) | 2021.02.01 |
UE4 Pawn과 Character의 차이점 (0) | 2021.02.01 |
UE4 인터페이스(Interface) (0) | 2021.01.23 |