GetWrappedLaunchDir()
啟動時的工作目錄,因為馬上要把工作目錄改為下面所說的exe所在目錄,所以會先把當前的緩存起來
FPlatformProcess::BaseDir()
這個是最基本的,就是當前exe文件所在目錄。
也是最早被計算的一個目錄,因為是所有依賴項的根結點,凡是要把相對路徑轉成全路徑的,都是基於這個目錄
可以用【-BaseFromWorkingDir】來把BaseDir指向當前工作目錄
FPaths::EngineDir()
引擎目錄,用來定位很多擎內置資源。
默認的值是../../../Engine/,而基准目錄就是上面的BaseDir
因為在發布后的目錄結構里,游戲目錄和引擎目錄是平級的頂層子目錄,exe文件會放在【游戲目錄/Binaries/Win64/】下面,退三層后剛好找到Engine
但是,這個目錄可以用【GForeignEngineDir】來重載,前提是按默認的方法沒找到引擎目錄(在引擎目錄下沒有Binaries子目錄),同時在GForeignEngineDir下有Binaries
這也是開發階段的默認配置,因為此時游戲還未打包,游戲目錄與引擎目錄不在一起,這時就只能通過GForeignEngineDir來定位引擎了
而此時GForeignEngineDir的實際值是什么呢?其實它是通過編譯時傳入的宏來定義的:
#if PLATFORM_DESKTOP #ifdef UE_ENGINE_DIRECTORY #define IMPLEMENT_FOREIGN_ENGINE_DIR() const TCHAR *GForeignEngineDir = TEXT( PREPROCESSOR_TO_STRING(UE_ENGINE_DIRECTORY) ); #else #define IMPLEMENT_FOREIGN_ENGINE_DIR() const TCHAR *GForeignEngineDir = nullptr; #endif #else #define IMPLEMENT_FOREIGN_ENGINE_DIR() #endif
其中UE_ENGINE_DIRECTORY在UEBuildTarget.cs里有設定:
string EnginePath = Utils.CleanDirectorySeparators(Utils.MakePathRelativeTo(ProjectFileGenerator.EngineRelativePath, Path.GetDirectoryName(OutputFilePath)), '/'); if (EnginePath.EndsWith("/") == false) { EnginePath += "/"; } GlobalCompileEnvironment.Config.Definitions.Add("UE_ENGINE_DIRECTORY=" + EnginePath);
而IMPLEMENT_FOREIGN_ENGINE_DIR這個宏的調用出現在UE4Game.cpp里:
#if IS_MONOLITHIC PER_MODULE_BOILERPLATE bool GIsGameAgnosticExe = true; TCHAR GInternalGameName[64] = TEXT(""); IMPLEMENT_DEBUGGAME() IMPLEMENT_FOREIGN_ENGINE_DIR() #endif
FPaths::RootDir()
根目錄,但其實是從引擎目錄反推出來的,也就是找到【/Engine】這一段去掉后上一層
但是如果引擎目錄里沒有/Engine這一段怎么辦(上面說過可以重載為一個自定義的)?
FPaths::GameDir()
游戲目錄,默認是與引擎目錄同級的,以游戲名命名的目錄,但是也可以通過【OverrideGameDir】重載
本來是很簡單,可是看代碼推導過程極其復雜,而且結果也好難理解,明明已經得到最精簡的絕對路徑了,可最后返回的竟然還是一個充滿../的相對路徑,還繞來繞去好幾層
+ FPaths::GameContentDir returned L"../../../UnrealEngine/../hz413/Content/" FString &
這幾個比較“頂級”的目錄,各有各的計算邏輯。
除此之外,其它的一些目錄就比較簡單了,基本上都是在EngineDir和GameDir里加上相應名字的子目錄,
如GameContentDir、GameConfigDir、GameSavedDir、GameIntermediateDir等等,每一種也有一個Engine的對應版。