라이라 게임 세팅

라이라 게임 샘플의 게임 세팅 개요입니다.

라이라 게임 세팅

라이라(Lyra)에는 유저 인터페이스(UI)와 기반 데이터를 만드는 프로세스를 간단하게 해주는 게임 세팅(GameSettings) 플러그인이 있습니다. 이 플러그인은 환경설정 파일 또는 서버에 저장할 데이터를 관리합니다.

예를 들어, 플레이어는 숲을 탐색하는 사진작가이고, 희귀 야생 동물에 관한 다큐멘터리를 찍어야 한다고 합시다. 캐릭터가 레벨의 특정 부분에 진입하면 게임 세팅 플러그인은 서버에 있는 데이터를 관리하여 레벨과 커뮤니케이션함으로써 현재 캐릭터가 있는 영역에 어떤 희귀 야생 동물이 나타날지 결정할 수 있습니다.

이 프레임워크에는 몇 가지 핵심 부분이 있습니다.

  • UGameSettingRegistry - 게임 세팅 레지스트리는 세팅 세트입니다. 싱글 레지스트리는 사용자에게 일부 혹은 전체가 노출될 수도 있지만, 게임의 세팅 중 하나 이상을 등록해야 합니다. 게임의 기타 시스템에 세팅이 필요한데 주요 게임 세팅이 없는 경우, 다른 레지스트리를 사용하는 것이 좋습니다.

  • UGameSetting - 모든 세팅의 베이스 클래스를 정의합니다. UI 목록의 모든 세팅이 게임 세팅으로 간주됩니다. 이 클래스는 이름, 설명, 종속성, 편집 조건과 같은 핵심 개념을 처리합니다.

  • UGameSettingValue - 값을 얻고 설정해야 하는 모든 세팅의 베이스 클래스를 구현합니다. 일부 세팅은 이 클래스에서 직접 상속받으며, 다음과 같은 클래스를 사용합니다.

     UGameSettingValueScalarDynamic, 
     UGameSettingValueDiscreteDynamic_Bool, 
     UGameSettingValueDiscreteDynamic_Number,  
     UGameSettingValueDiscreteDynamic_Enum.
  • UGameSettingCollection - 조직 세팅을 정의합니다. 게임 세팅 컬렉션(Game Setting Collection)은 세팅을 그룹화하는 데 사용됩니다. 예를 들어 컬렉션으로 헤더 목록을 생성하고자 했다면, 그 컬렉션은 헤더가 있는 그룹을 나타냅니다.

  • FGameSettingEditCondition - 각 세팅에는 편집 조건 세트가 붙어 있습니다. 이러한 편집 조건은 세팅이 비활성화되거나, 숨겨지거나, 소멸될 때 쿼리하는 로직을 인코딩하는 기능을 제공합니다.

세팅 만들기

코드에 작성하는 세팅 함수는 대부분 다음과 같습니다.

UGameSettingValueScalarDynamic* Setting = NewObject<UGameSettingValueScalarDynamic>();
Setting->SetDevName(TEXT("OverallVolume"));
Setting->SetDisplayName(LOCTEXT("OverallVolume_Name", "Overall"));
Setting->SetDescriptionRichText(LOCTEXT("OverallVolume_Description", "Adjusts the volume of everything."));
Setting->SetDynamicGetter(GET_LOCAL_SETTINGS_FUNCTION_PATH(GetOverallVolume));
Setting->SetDynamicSetter(GET_LOCAL_SETTINGS_FUNCTION_PATH(SetOverallVolume));
Setting->SetDefaultValue(GetDefault<ULyraSettingsLocal>()->GetOverallVolume());
Setting->SetDisplayFormat(UGameSettingValueScalarDynamic::ZeroToOnePercent);
Setting->AddEditCondition(FWhenPlayingAsPrimaryPlayer::Get());

모든 세팅에는 레지스트리 전체에서 고유한 DevName 이 있어야 하고, DisplayName 이 필요합니다.

DescriptionRichText 는 대부분의 세팅에 필요하며, 필요한 세팅이 모두 있는지 확인할 때도 사용됩니다. UMG 리치 텍스트 위젯 형식에서는 리치 텍스트(Rich text)를 표준으로 사용합니다. 플레인 텍스트(Plain text)는 검색을 색인할 때 파싱되어 빠지기 때문입니다. 다이내믹 게터(DynamicGetter)와 다이내믹 세터(DynamicSetter)는 런타임에도 세팅에 액세스할 수 있게 해 줍니다. 데이터에 지속해서 액세스하려면, 다음 명령을 사용하면 됩니다.

LocalPlayer-> GetLocalSettings()->GetOverallVolume()

각 세팅에 중복되지만, 다이내믹 게터와 세터가 제공된 매크로를 사용하여 빌드된 FGameSettingDataSourceDynamic 을 갖게 됩니다.

다이내믹 세터와 다이내믹 게터를 사용하려면 메타데이터 프로퍼티 지정자(Metadata Property Specifiers)를 사용하여 LocalPlayer의 데이터에 액세스할 수 있어야 합니다. 지정자를 사용하면 초기화할 때 다음과 같은 조건이 보장됩니다.

커스텀 세팅

세팅에 내장된 클래스를 사용하면 대부분의 필요 사항을 충족할 수 있습니다. 그러나 세팅에 더 복잡한 로직이 필요한 경우가 있을 수 있습니다. 예를 들어 게임에 패키지로 포함된 사용 가능한 언어를 모두 가져와야 한다고 합시다.

UGameSettingValueDiscrete_Language* Setting = NewObject<UGameSettingValueDiscrete_Language>();
Setting->SetDevName(TEXT("Language"));
Setting->SetDisplayName(LOCTEXT("LanguageSetting_Name", "Language"));
Setting->SetDescriptionRichText(LOCTEXT("LanguageSetting_Description", "게임의 언어입니다."));
Matchmaking->AddSetting(Setting);

UGameSettingValueDiscrete_Language 는 저장한 언어 및 문화 세팅을 직접 바꿉니다.

편집 조건

FGameSettingEditCondition의 모든 편집 조건 하위 클래스는 다음 중 적용해야 하는 조건이 있는 경우 세팅에 대해 비활성화, 숨기기, 리셋 방지, 제외하기 등을 수행하는 역할입니다.

  • FWhenCondition - 조건을 인라인 람다로 작성할 수 있게 합니다.

  • FWhenPlatformHasTrait - 플랫폼 특성에 따라 세팅을 숨기거나 비활성화하는 용도입니다. 예를 들면 다음과 같은 특성이 있습니다.

    • 플랫폼이 키보드와 마우스를 지원하나요?

    • 플랫폼이 화면 해상도 변경을 지원하나요?

소스 코드 예시를 몇 가지 살펴보면, 세팅을 제거할 때나 라이라의 기타 일반 영역에서 #if PLATFORM_FEATURE 같은 디파인을 사용하지 않는다는 것을 파악할 수 있습니다. '에디터에서 플레이(Play In Editor, PIE)'로 테스트할 때 다른 플랫폼을 테스트하는 옵션을 사용할 수 있고, 모든 것을 동적으로 재평가할 수 있기 때문에 라이라에서는 플랫폼 특성을 대신 사용합니다. 따라서 가능하다면 FWhenPlatformHasTrait 을 사용하는 편을 권장합니다.

  • FWhenPlayingAsPrimaryPlayer - 다른 로컬 플레이어가 특정 세팅에 액세스할 수 없게 하고 싶다면, 이 인스턴스로 특정 조건을 편집하여 첫 번째 플레이어만 액세스할 수 있게 제한할 수 있습니다.

예를 들어 클래스 LyraGameSettingRegistry_Video.cpp 에 있는 해상도 세팅을 다음과 같이 설정할 수 있습니다.

Setting->AddEditDependency(WindowModeSetting);
Setting->AddEditCondition(MakeShared<FWhenCondition>([WindowModeSetting](const ULocalPlayer*, FGameSettingEditableState& InOutEditState) {

    if (WindowModeSetting->GetValue<EWindowMode::Type>() == EWindowMode::Windowed)

    {

        InOutEditState.Disable(LOCTEXT("ResolutionWindowed_Disabled", "창 모드가 <strong>창 모드</>로 설정된 경우, 해상도는 창 크기에 따라 자유롭게 조정됩니다."));

    }

    else if (WindowModeSetting->GetValue<EWindowMode::Type>() == EWindowMode::WindowedFullscreen)

    {

        InOutEditState.Disable(LOCTEXT("ResolutionWindowedFullscreen_Disabled", "창 모드가 <strong>전체 창 모드</>로 설정된 경우, 해상도는 바탕 화면 네이티브 해상도와 일치해야 합니다."));

    }
}));

조건 트랙을 편집하여 활성화 , 비활성화 , 숨겨짐 으로 세팅을 토글할 수 있습니다. 이 인스턴스는 사용자가 런타임에 프로젝트 세팅을 변경하려 하면 디버거로 트레이스할 수 있는 설명을 제공하도록 설계되었습니다. 아래 이미지에서는 창 모드의 편집 조건이 '비활성화'로 토글되어 있습니다. 따라서 엔진은 사용자가 왜 세팅을 변경할 수 없는지 알 수 있도록 메시지를 반환합니다.

LyraWarningWindow

유저 인터페이스

유저 인터페이스는 UGameSettingVisualDataUGameSettingPanel 클래스로 구성되어 있습니다. 게임 세팅 패널은 디스플레이 처리를 담당하며, 레지스트리와 필터를 제공하면 패널에서 세팅을 보여줍니다. 이러한 세팅이 어떻게 정의되는지는 게임 세팅 시각화 데이터(Game Setting Visual Data)에서 확인할 수 있습니다. 게임 세팅 시각화 데이터에는 세팅에서 UGameSettingListEntryBaseUGameSetting 클래스에 연결하기 위해 사용하는 규칙이 포함됩니다.

LyraGameSettingRegistry

게임 세팅 레지스트리 시각화 데이터에는 패널이 어떻게 표시되어야 하는지에 대한 세부 사항이 포함됩니다.

데이터 소스

`FGameSettingDataSource`
`FGameSettingDataSourceDynamic`

`GET_SHARED_SETTINGS_FUNCTION_PATH`
`GET_LOCAL_SETTINGS_FUNCTION_PATH`