[UE] User Interface(UI)
0. Slate
Slate
는 Unreal Engine의 C++ 기반 저수준 UI 프레임워크다.
모든 Slate 위젯은 SWidget
클래스를 부모로 갖는다.
항목 | 설명 |
---|---|
목적 | 고성능, 저수준 UI 렌더링 |
기반 구조 | SWidget 기반(Non-UObject, 경량 구조) |
제작 방법 | 순수 C++ 코드로 구성 |
사용 예 | 커스텀 위젯, 에디터 UI, 성능이 중요한 UI 등 |
관리 방식 | 직접 메모리 관리(SharedPtr 기반) |
이벤트 | Slate Event(OnClicked , OnMouseDown ) 등 |
성능 | UMG에 비해 가볍고 빠름 |
0-1. Slate의 기본 구조
Slate는 아래처럼 C++에서 직접 위젯을 생성 및 구성한다.
TSharedRef<SVerticalBox> MySlateUI =
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(STextBlock)
.Text(FText::FromString("Hello, Slate!"))
]
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SButton)
.Text(FText::FromString("Click Me"))
.OnClicked(this, &MyClass::OnClickButton)
];
SNew
, Slot()
, []
등의 구문은 Slate 고유 문법이다.
0-2. Slate 특징
항목 | 설명 |
---|---|
SWidget |
모든 Slate 위젯의 부모 클래스(텍스트, 버튼 등 전부 상속) |
TSharedRef , TSharedPtr |
메모리 관리용 스마트 포인터 사용(GC 아님) |
SNew 매크로 |
Slate 위젯을 선언적으로 생성 |
이벤트 바인딩 | OnClicked , OnMouseEnter 등 함수 포인터 방식 |
스타일 | FSlateStyleSet , FSlateBrush , FSlateFontInfo 등을 통한 커스터마이징 |
1. UMG(Unreal Motion Graphics)
Slate를 Blueprint-friendly하게 감싼 고수준 UI 시스템이다.
UUserWidget
은 내부적으로 SWidget
들이 실제 렌더링을 처리한다.
항목 | 설명 |
---|---|
목적 | 사용자 친화적인 UI 제작(디자이너, BP) |
기반 구조 | UObject 기반(UUserWidget ) |
제작 방법 | 에디터 + 블루프린트 + 일부 C++ |
사용 예 | 인벤토리, HUD, 메뉴 등 대부분 UI |
관리 방식 | GC 대상(UObject) |
이벤트 | BindWidget, BP Event, UFUNCTION 등 |
성능 | Slate에 비해 무거움 |
1-1. 구성 요소
구성 | 설명 |
---|---|
UUserWidget |
UI 화면을 표현하는 가장 기본 단위 클래스 |
CanvasPanel , VerticalBox 등 |
레이아웃 위젯 |
Button , TextBlock , Image 등 |
시각적 위젯 |
Blueprint Widget |
UUserWidget을 상속한 에디터 기반 블루프린트 UI |
1-2. 동작 방식
- C++로
UUserWidget
을 상속받은 클래스를 만든다. - 에디터에서 그걸 상속받은 위젯 블루프린트를 만들어 UI를 구성한다.
- C++ 또는 블루프린트에서 이 위젯을
CreateWidget()
이나UWidgetComponent
로 생성 또는GetWidgetFromName()
함수를 통해 위젯을 찾아 화면에 표시한다.
UUserWidget 클래스를 상속받아 블루프린트로 만든 UI를 어떻게 다시 C++ 코드에서 GetWidgetFromName()
함수를 통해 얻어올 수 있을까? 이를 이해하려면 Widget Tree를 알아야 한다.
1-3. Widget Tree
UUserWidget
내부에 자동 생성되는 트리 구조의 위젯 계층이다. 모든 자식 위젯(Button, TextBlock 등)은 Widget Tree에 등록된다. GetWidgetFromName()
은 이 WidgetTree
안에서 위젯을 찾는다.
에디터에서 구성한 UI 요소들은 부모 C++ 클래스가 아닌 해당 블루프린트 인스턴스의 WidgetTree
에 들어가며, C++ 코드에서 GetWidgetFromName()
으로 접근할 수 있는 이유가 바로 이것이다.
에디터에서 위젯 블루프린트(BP)를 만들 때, 이 위젯 BP는 어떤 C++ 부모 클래스(ex. UMyUserWidget
)를 상속받고 있다. BP 내부에서 Button, TextBlock 등 여러 위젯을 Designer탭에서 배치하면 이 UI 구성 정보는 BP 내부에 저장된다. 이후 런타임에서 CreateWidget()
이나 WidgetComponent
로 인스턴스화할 때, 이 구조가 부모 C++ 클래스의 인스턴스(ex. UMyUserWidget
)의 WidgetTree에 담기게 된다. 따라서 GetWidgetFromName()
은 반드시 실제 인스턴스가 생성된 뒤에 호출해야 한다.
구조 예시
UUserWidget (MyWidget)
- CanvasPanel
- TextBlock (TitleText)
- Button (StartButton)
- TextBlock (ButtonLabel)
이 모든 구조는 MyWidget->WidgetTree
에 저장되어 있고, GetWidgetFromName(TEXT("StartButton"))
으로 StartButton
을 찾을 수 있다.
1-4. Panel
여러 자식 위젯을 담는 컨테이너 위젯이다(ex. CanvasPanel
, VerticalBox
, Overlay
).
Panel
은 자식 위젯을 여러 개 가질 수 있는 부모 위젯이며, 레이아웃을 결정한다.
대표적인 Panel의 종류로는,
CanvasPanel
: 절대 좌표 배치(픽셀 단위 위치)VerticalBox
: 위에서 아래로 차례대로 배치HorizontalBox
: 왼쪽에서 오른쪽으로 배치Overlay
: 자식 위젯을 겹쳐서 배치GridPanel
: 행/열 격자 배치
등이 있다.
1-5. Slot
Slot
은 패널이 각 자식 위젯에 대해 가지는 부가 정보이다(ex. UCanvasPanelSlot
, UVerticalBoxSlot
). 위치, 정렬, Padding 등 UI 배치를 제어하며, 패널 종류마다 대응되는 Slot 클래스가 다르다.
UButton* Button = WidgetTree->ConstructWidget<UButton>();
//패널에 추가 -> 해당 패널 전용 Slot이 반환됨
UCanvasPanelSlot* Slot = Cast<UCanvasPanelSlot>(Canvas->AddChild(Button));
if (Slot)
{
Slot->SetPosition(FVector2D(100, 100));
Slot->SetSize(FVector2D(200, 50));
}
Leave a comment