ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Unreal Engine] Finding files
    Unreal Engine 5._ 2023. 5. 22. 16:17

    프로그램을 개발하다보면, 컴파일되는 코드 외에 다른 경로의 파일에 의존해야 하는 경우가 있습니다.

    그 경우에는 대개 특정 디렉토리의 특정 파일에 의존하는 경우가 있을 수 있고

    불특정 디렉토리의 불특정 다수의 파일에 의존하는 경우가 있을 수 있습니다.

    전자의 경우라면 상대적으로 정적인 경로를 고정적으로 이용할 수 있겠지만, 후자의 경우는 조금 난해합니다.

     

    이번 글에서는 후자의 경우에 유용하게 쓰일 수 있는, 언리얼 엔진에서 파일을 탐색하는 방법을 살펴보도록 하겠습니다.

     


     

    1. FindFiles

     

    더보기

    FindFiles함수에 대한 설명은 언리얼 엔진 공식 문서에 있습니다.

    Unreal Engine Documentation : IPlatformFile::FindFile

     

    해당 함수를 사용하는 간단한 예제는 다음과 같습니다.

    TArray<FString> foundFiles;
    FPlatformFileManager::Get().GetPlatformFile().FindFiles(
        foundFiles,
        TEXT("{finding path}"),
        TEXT("{file extension}")
    };

    FindFiles함수는 static함수가 아니기 때문에, IPlatformFile객체를 받아와야 합니다.

    그것을 위한 코드가 함수를 FindFiles함수 이전에 호출된 FPlatformFileManager의 함수들입니다.

     

    위 호출에 전달된 인자들은 각각 다음과 같은 역할을 수행합니다.

    • foundFiles : 탐색의 결과를 담을 변수입니다. 결과는 절대경로로써 표현되어 있습니다.
    • TEXT("{finding path}") : 탐색을 수행할 디렉토리의 경로입니다.
    • TEXT("{file extension}") : 탐색할 파일의 확장자를 제한합니다. 비어있을 경우 모든 파일을 탐색합니다.

     

    2. FPaths

     

    더보기

    위 문단에서, FindFiles의 간단한 사용 예를 살펴보았습니다.

    파일을 탐색할 때에는 탐색을 수행할 경로가 매우 중요합니다.

    하지만 플랫폼에 종속적인 프로그램의 특성 상, 탐색을 수행할 경로를 고정된 문자열로 입력하는 것은 문제가 발생할 확률이 매우 큽니다.

     

    언리얼 엔진에서는 이러한 상황을 위해 경로와 관련된 값을 받아올 수 있는 FPaths라는 객체를 만들었습니다.

    FPaths에서 이용할 수 있는 함수의 목록은 언리얼 엔진 공식 문서에 기술되어 있습니다.

    Unreal Engine Documentation : FPaths

     

    간단하게 몇 가지만 살펴보면 다음과 같습니다.

    UE_LOG(LogTemp, Log, TEXT("EngineDir : %s"), *FPaths::EngineDir());
    UE_LOG(LogTemp, Log, TEXT("ProjectDir : %s"), *FPaths::ProjectDir());
    UE_LOG(LogTemp, Log, TEXT("EngineConfigDir : %s"), *FPaths::EngineConfigDir());
    UE_LOG(LogTemp, Log, TEXT("ProjectConfigDir : %s"), *FPaths::ProjectConfigDir());
    UE_LOG(LogTemp, Log, TEXT("EngineContentDir : %s"), *FPaths::EngineContentDir());
    UE_LOG(LogTemp, Log, TEXT("ProjectContentDir : %s"), *FPaths::ProjectContentDir());
    UE_LOG(LogTemp, Log, TEXT("EngineUserDir : %s"), *FPaths::EngineUserDir());
    UE_LOG(LogTemp, Log, TEXT("ProjectUserDir : %s"), *FPaths::ProjectUserDir());
    UE_LOG(LogTemp, Log, TEXT("GameDevelopersDir : %s"), *FPaths::GameDevelopersDir());
    UE_LOG(LogTemp, Log, TEXT("GameSourceDir : %s"), *FPaths::GameSourceDir());
    UE_LOG(LogTemp, Log, TEXT("LaunchDir : %s"), *FPaths::LaunchDir());

    위 코드를 실행할 경우, 다음과 같은 로그를 확인할 수 있습니다.

    LogTemp: EngineDir : ../../../Engine/
    LogTemp: ProjectDir : D:/UnrealProject/CPPTutorial/
    LogTemp: EngineConfigDir : ../../../Engine/Config/
    LogTemp: ProjectConfigDir : D:/UnrealProject/CPPTutorial/Config/
    LogTemp: EngineContentDir : ../../../Engine/Content/
    LogTemp: ProjectContentDir : D:/UnrealProject/CPPTutorial/Content/
    LogTemp: EngineUserDir : C:/Users/{UserName}/AppData/Local/UnrealEngine/5.0/
    LogTemp: ProjectUserDir : D:/UnrealProject/CPPTutorial/
    LogTemp: GameDevelopersDir : D:/UnrealProject/CPPTutorial/Content/Developers/
    LogTemp: GameSourceDir : D:/UnrealProject/CPPTutorial/Source/
    LogTemp: LaunchDir : D:\UnrealProject\CPPTutorial/

    해당 코드가 실행된 프로젝트의 이름은 CPPTutorial이고, 경로는 D\UnrealProject입니다.

    출력 로그 중, OS의 계정명에 관한 내용은 {UserName}으로 수정했습니다.

    보실 때 참고하시기 바랍니다.

     

    위와 같이 FPath클래스를 이용하면 파일 탐색에 필요한 경로의 의존성을 줄일 수 있습니다.

     

    3. GetDefaultPathSeparator

     

    더보기

    위 문단에서 기본적인 일부 경로들을 가져오는 방법을 알아보았습니다.

    만약 프로젝트의 디렉토리 배치가 더 복잡해질 경우, 받아온 경로에 추가적인 경로를 더해야 하는 상황이 발생합니다.

    그 외에도, 읽어온 경로를 잘라서 일부만 이용해야 하는 상황이 생길 수 있습니다.

     

    이 때 스트링을 자르는 Delimiter로 경로 구분자 (Path separator)를 사용합니다.

    문제는 이 Path separator가 OS별로 다르다는 것 입니다.

    만약 한 OS에 종속적인 프로그램이 아닐 경우, 이는 큰 문제가 될 수 있습니다.

     

    언리얼 엔진에서는 이를 위해 Path separator를 반환하는 함수가 있습니다.

    함수의 이름은 GetDefaultPathSeparator로, 플랫폼에 맞는 Path separator를 반환합니다.

    해당 함수는 static함수로, FGenericPlatformMisc클래스의 멤버 함수입니다.

    for (auto& i : foundFiles) {
        TArray<FString> splitStr;
        i.ParseIntoArray(splitStr, FGenericPlatformMisc::GetDefaultPathSeparator());
        GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan,
            FString::Printf(TEXT("File : %s"), *splitStr.Last()));
    }

    위 코드는 FindFiles함수로 찾은 파일의 이름만 출력하는 코드입니다.

    경로를 구분자로 나눌 때, 고정된 문자가 아닌 GetDefaultPathSeparator함수를 사용했습니다.

     


     

    언리얼 엔진에서 파일을 탐색하는 방법과, 파일 탐색에 필요한 경로와 관련된 기능을 알아보았습니다.

     

    도움이 되셨기를 바랍니다.

    감사합니다.

    댓글

Designed by Tistory.