[UE5] UI Design - Widget Blueprint를 Color Palette로 활용하기 (ProjectVT 개발기)
Widget Blueprint 내부의 여러 다양한 Component에 사용할 여러 색상들을 웹 디자인 할 때처럼 언리얼 엔진에서도 하나의 객체(또는 전역변수)로 관리할 필요성이 느껴졌다.
제작하고 있는 게임의 UI 시스템이 크게 복잡하지 않고 간단한 앱과 비슷한 정도라 디자인 방식으로 Material Design을 채택하였고 그에 따라 Primary, Secondary, Background, Surface등 색상을 모두 담은 Color Palette를 준비하였다.
이번 포스팅은 Widget Blueprint의 Component의 색상을 일괄적으로 Color Palette를 기반으로 설정하기 위해 찾아본 것들을 정리한 포스팅이다.
1. 언리얼 엔진 내부의 Color Picker 사용하기
Color Picker 상단을 보면 여러 색을 저장할 수 있는 ColorTheme을 만들 수 있다.
지정한 색상들을 하나하나 찾아서 Color Picker에 넣어두어 여러 Color Theme을 만들어두면 Editor에서 쉽게 고를 수 있다.
Theme, Color에 모두 이름을 붙일 수 있기 때문에 Theme의 이름을 Material Color Theme 1
각 색상의 이름을 Primary, Secondary로 붙여 관리가 가능하다.
하지만 협업에서 문제가 있다. Editor 내부에 저장되는 값이기 때문에 Editor의 설정을 저장하는 파일에 기록되어 공유가 매끄럽지 않다.
# Root/Saved/Config/WindowsEditor/EditorPerProjectUserSetting.ini
[ColorThemes]
Theme0=2
Theme0Color0=(R=11.118751,G=0.918278,B=1.000000,A=1.000000)
Theme0Label0=
Theme0Color1=(R=312.936188,G=0.818123,B=1.000000,A=1.000000)
Theme0Label1=
Theme0Color2=(R=19.142269,G=0.667094,B=1.000000,A=1.000000)
Theme0Label2=
Theme0Color3=(R=207.255310,G=0.193341,B=1.000000,A=1.000000)
Theme0Label3=
Theme0Color4=(R=235.397324,G=0.816264,B=1.000000,A=1.000000)
Theme0Label4=
Theme0Color5=(R=271.355865,G=0.880455,B=1.000000,A=1.000000)
Theme0Label5=
Theme0Color6=(R=134.085754,G=1.000000,B=1.000000,A=1.000000)
Theme0Label6=
2. Widget Blueprint로 관리하기
Widget Blueprint를 만들고 Uniform Grid Panel을 만들어 내부에 Color 속성을 가진 Component를 줄지어 배치하는 방식이다. (예시로 5개 색상만 매치하였다)
처음에는 단순하게 ini 파일을 따로 만들어 내부에 색상 코드를 적어 이를 로드하여 static 변수로 설정하려 하였으나 언리얼 엔진에서 제공하는 Color Picker도 사용가능하고 색상을 바로 보기에도 편리한 Widget Blueprint 방식이 더 협업하기 좋다고 생각하여 이를 사용하기로 하였다.
Color Palette를 Widget Blueprint로 관리하기로 하였다면 다음은 이 색상들을 다른 Widget blueprint 클래스의 컴포넌트가 활용하기 용이하게 만들어야 한다.
Color 속성을 가진 Component 들에 정한 디자인 방법론에 따른 이름을 붙이고 이를 변수로 설정한다.
Widget Blueprint에서 함수를 만들어 각 LinearColorStructure 자료형을 반환하도록 한다.
색상을 설정하고자 하는 다른 Widget Blueprint의 Component들을 보면 Button, Text, Image 등 Color and Opacity를 속성으로 가지는 Component들이 있다.
Widget Blueprint가 생성된 이후 호출되는 이벤트인 Event Construct에 실행 핀을 연결하여 아래와 같이 Auto, Skip, Log button의 Color와 Opacity를 바꿀 수 있다.
Color Palette의 색상을 가져오기 위해 Get Color and Opacity 함수를 직접 정의하였다.
Get Color and Opacity 함수에 대해 설명하기 전에 Color Palette Blueprint의 Construction 시점, 방식에 대해 설명하겠다.
거의 모든 Widget Blueprint에서 활용할 Color Palette Blueprint를Global Widget 처럼 활용하기 위해 GameInstance에서 Color Palette Widget을 생성하고 이를 참조하도록 하였다.
정의한 Get Color and Opacity는 GameInstance를 가져와 Casting하고 멤버인 Color Palette의 참조를 활용하여 색상을 가져오는 방식으로 구현하여 초기 Blueprint 세팅을 마쳤다.
개선하기
가장 빠르게 동작을 목표로 만든것이라서 문제가 매우 많다.
기존에 만든 Widget Blueprint가 직접 정의한 Class를 상속하지 않고 있기 때문에 함수를 매번 새로 정의하고 있고 여러 색상도 하드코딩되어 있어 색상이 늘어날 때마다 함수를 두 클래스에서(Color Palette, Target Class) 추가로 만들어야 한다. 또한 여러 Color Palette를 비교할 때 수정이 필요한 부분이 많다.
UserWidget를 상속받는 Child Class로 CustomUserWidget을 만들고 Interface를 사용하여 Color Opacity가 설정가능한 Component인지 확인하여 Color Palette의 색상을 받아오는 함수를 정의 후 enum을 parameter로 받아 알아보기 쉽도록 만들었으며 추가로 ColorPalette도 선택 가능하도록 하여 여러 디자인 Theme을 비교해볼 수 있도록 하였다.
ColorPalette Widget Blueprint도 각 색상을 반환하는 함수, 색상 변수, Layout을 사전 정의한 Parent Class를 만들고 이를 상속하도록 하여 반복작업을 줄였다.
UENUM()
enum class EColorType : uint8
{
Primary,
PrimaryVariant,
Secondary,
SecondaryVariant,
Surface,
Background,
Error,
OnPrimary,
OnSecondary,
OnSurface,
OnBackground,
OnError
};
// Pseudo code for
static FLinearColor GetUIColor(class UUserWidget* ColorPaletteWidget, EColorType ColorType, float Opacity);
FLinearColor UBFL_Util::GetUIColor(UUserWidget* ColorPaletteWidget, EColorType ColorType, float Opacity)
{
switch (ColorType)
{
case EVTColorType::Primary:
// ...
// ...
}
return ResultColor * Opacity;
}