슬레이트 UI 시스템 기초
슬레이트(Slate)는 언리얼 엔진의 저수준 UI 프레임워크로, C++에서 직접 UI를 구현할 때 사용됩니다. UMG가 디자이너와 프로그래머 모두를 위한 고수준 UI 도구라면, 슬레이트는 프로그래머를 위한 강력하고 유연한 UI 시스템입니다.
슬레이트 위젯의 구조
슬레이트 위젯은 기본적으로 SWidget
을 상속받아 구현됩니다. 가장 일반적으로 사용되는 기본 클래스는 SCompoundWidget
입니다.
class MYPROJECT_API SMyWidget : public SCompoundWidget
{
SLATE_BEGIN_ARGS(SMyWidget)
: _SomeAttribute()
{}
SLATE_ARGUMENT(FString, SomeAttribute)
SLATE_END_ARGS()
void Construct(const FArguments& InArgs);
};
void SMyWidget::Construct(const FArguments& InArgs)
{
ChildSlot
[
SNew(STextBlock)
.Text(FText::FromString(InArgs._SomeAttribute))
];
}
이 예제에서 SLATE_BEGIN_ARGS
와 SLATE_END_ARGS
매크로는 위젯의 속성을 정의합니다. Construct
함수에서는 위젯의 실제 구조를 정의합니다.
주요 슬레이트 클래스
SWidget
: 모든 슬레이트 위젯의 기본 클래스SCompoundWidget
: 단일 자식을 가질 수 있는 복합 위젯SPanel
: 여러 자식을 가질 수 있는 패널 위젯SLeafWidget
: 자식을 가질 수 없는 리프 위젯
커스텀 슬레이트 위젯 생성
커스텀 슬레이트 위젯을 생성할 때는 주로 SCompoundWidget
을 상속받아 구현합니다.
class SCustomButton : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SCustomButton)
: _ButtonText()
, _OnClicked()
{}
SLATE_ATTRIBUTE(FText, ButtonText)
SLATE_EVENT(FOnClicked, OnClicked)
SLATE_END_ARGS()
void Construct(const FArguments& InArgs)
{
ChildSlot
[
SNew(SButton)
.Text(InArgs._ButtonText)
.OnClicked(InArgs._OnClicked)
];
}
};
이 예제에서는 SButton
을 래핑하는 커스텀 버튼 위젯을 생성합니다.
슬레이트 스타일 설정
슬레이트는 강력한 스타일링 시스템을 제공합니다. 스타일은 주로 FSlateStyleSet
을 통해 정의됩니다.
FSlateStyleSet* StyleSet = new FSlateStyleSet("CustomStyle");
StyleSet->Set("CustomButton", FButtonStyle()
.SetNormal(FSlateBoxBrush(FPaths::ProjectContentDir() / TEXT("UI/ButtonNormal.png"), FMargin(10.0f/32.0f)))
.SetHovered(FSlateBoxBrush(FPaths::ProjectContentDir() / TEXT("UI/ButtonHovered.png"), FMargin(10.0f/32.0f)))
.SetPressed(FSlateBoxBrush(FPaths::ProjectContentDir() / TEXT("UI/ButtonPressed.png"), FMargin(10.0f/32.0f)))
);
FSlateStyleRegistry::RegisterSlateStyle(*StyleSet);
이벤트 처리 구현
슬레이트에서 이벤트 처리는 주로 델리게이트를 통해 이루어집니다.
SNew(SButton)
.OnClicked(FOnClicked::CreateLambda([this]()
{
// 클릭 이벤트 처리
return FReply::Handled();
}))
레이아웃 및 정렬
슬레이트는 다양한 레이아웃 위젯을 제공합니다.
예를 들어, SVerticalBox
와 SHorizontalBox
는 가장 기본적인 레이아웃 위젯입니다.
SNew(SVerticalBox)
+SVerticalBox::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(FText::FromString("Centered Text"))
]
+SVerticalBox::Slot()
.HAlign(HAlign_Right)
[
SNew(STextBlock)
.Text(FText::FromString("Right-aligned Text"))
]
UMG와 슬레이트의 차이점
- 사용 난이도 : UMG는 비주얼 디자이너를 제공하여 더 쉽게 UI를 만들 수 있습니다.
- 성능 : 슬레이트는 더 낮은 수준에서 동작하므로 일반적으로 더 높은 성능을 제공합니다.
- 유연성 : 슬레이트는 더 많은 커스터마이징 옵션을 제공합니다.
고성능 UI 구현 전략
- 위젯 재사용 : 가능한 한 위젯을 재사용하여 생성 비용을 줄입니다.
- 레이아웃 최적화 : 복잡한 레이아웃 계산을 최소화합니다.
- 드로우 콜 최소화 : 가능한 한 드로우 콜을 줄이도록 UI를 설계합니다.
에디터 UI 확장
슬레이트는 언리얼 에디터의 UI를 확장하는 데 주로 사용됩니다.
FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
TSharedPtr<FTabManager> LevelEditorTabManager = LevelEditorModule.GetLevelEditorTabManager();
LevelEditorTabManager->RegisterTabSpawner("CustomTab", FOnSpawnTab::CreateLambda([](const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SCustomWidget)
];
}));
성능 최적화 기법
- 캐싱 : 자주 변경되지 않는 위젯 부분을 캐싱합니다.
- 가시성 최적화 : 화면에 보이지 않는 위젯의 업데이트를 최소화합니다.
- 지연 생성 : 필요할 때만 위젯을 생성합니다.
디버깅 방법
- 슬레이트 위젯 리플렉터 : 에디터에서 제공하는 도구로 위젯 계층 구조를 분석할 수 있습니다.
- 로깅 :
UE_LOG
매크로를 사용하여 위젯의 상태와 이벤트를 로깅합니다. - 시각적 디버깅 :
DrawDebugLine
과 같은 함수를 사용하여 위젯의 경계를 시각화합니다.
슬레이트 UI 시스템은 강력하고 유연하지만, 학습 곡선이 가파르다는 단점이 있습니다. 그러나 한번 익숙해지면, 고성능의 커스텀 UI를 구현하는 데 매우 유용한 도구가 됩니다. 특히 에디터 확장이나 고도로 최적화된 게임 내 UI가 필요한 경우에 슬레이트의 강점이 두드러집니다.