UE 5.4에서 SaveConfig() 가 ini 파일을 저장하지 못할 때

결론

5.4.1 에서 발생하고 있는 증상입니다.

config 를 지정한 UCLASS 는 경우에 따라 ini 파일을 생성하거나 저장하지 못하고 있습니다.

두 가지 방법의 우회법이 있습니다.

방법 1. config 파일의 파일 이름에 “Editor” 혹은 “User” 를 추가합니다

이런 식입니다. 만일 이런 상태일 경우:

1
2
UCLASS(config = SomeConfigFileName)
class SOMEPROJECTNAME_API USomeClassName : public UObject

아래처럼 바꿉니다

1
2
UCLASS(config = SomeConfigFileNameUser) // 혹은 SomeConfigFileNameEditor 라고 해도 OK.
class SOMEPROJECTNAME_API USomeClassName : public UObject

방법 2. config ini 파일을 수동으로 생성한 뒤, 해당 ini 파일에 다음의 내용을 추가합니다

1
2
[SectionsToSave]
bCanSaveAllSections=true

설명

이번의 디버깅의 목표 중 하나는, “최대한 시간을 덜 쓴다"였습니다.

따라서 이번 포스트에서 정확한 원인을 설명하기는 힘듭니다.

이에 대해서는 양해를 구합니다.

ini 파일이 제대로 저장되지 않고 있는 증상을 발견한 뒤, 다음의 포럼 게시물을 찾을 수 있었습니다.

https://forums.unrealengine.com/t/5-4-config-not-saving-correctly/1860118

또한 디스코드에서도 유사한 언급을 찾았었습니다.

https://discord.com/channels/187217643009212416/846520322642411570/1240002393618256036

저 bCanSaveAllSections 가 문제의 원인에 가까이 있다는 것을 염두에 두고, ini 파일이 저장되는 과정을 디버깅해봤습니다.

그 도중에 다음의 코드를 발견했습니다. 이는 5.3엔 없던, 5.4에서 새로 추가된 코드입니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
    // check if the config file wants to save all sections
    bool bLocalSaveAllSections = false;
    // Do not report the read of SectionsToSave. Some ConfigFiles are reallocated without it, and reporting
    // logs that the section disappeared. But this log is spurious since if the only reason it was read was
    // for the internal save before the FConfigFile is made publicly available.
    const FConfigSection* SectionsToSaveSection = ConfigFile->FindSection(SectionsToSaveString);
    if (SectionsToSaveSection)
    {
      const FConfigValue* Value = SectionsToSaveSection->Find(SaveAllSectionsKey);
      if (Value)
      {
        const FString& ValueStr = UE::ConfigCacheIni::Private::FAccessor::GetValueForWriting(*Value);
        bLocalSaveAllSections = FCString::ToBool(*ValueStr);
      }
    }

    // we can always save all sections of a User config file, Editor* (not Editor.ini tho, that is already handled in the normal method)
    bool bIsUserFile = BaseIniName.Contains(TEXT("User"));
    bool bIsEditorSettingsFile = BaseIniName.Contains(TEXT("Editor")) && BaseIniName != TEXT("Editor");

    ConfigFile->bCanSaveAllSections = bLocalSaveAllSections || bIsUserFile || bIsEditorSettingsFile;

여기서도 문자열 하드코딩을 보고 놀랐습니다. 처음 봤을 때는 믿기 힘들었으며, 지금도 저에게는 받아들이기 고통스러운 부분입니다. ini 에 섹션별 저장과 관련된 새로운 기능을 추가하면서 피치 못하게 추가된 결정이 아니었을까 추측하고 있습니다. 다만 예전 포스팅에서도 언급했듯이, 문자열 하드코딩은 생각보다 엔진에서 자주 사용되고 있는 것 같습니다. 이것은 향후 개발 과정에서 기억해놓고 싶은 부분입니다.

태그