简介
介绍UE4工程目录结构[1]以及常用的目录操作接口[2]。UE4将目录分为:
- 引擎目录
- 项目目录
其中一些子目录是两个都有的,称之为通用目录,有一些目录是引擎特有的。当我们从github
https://github.com/EpicGames/UnrealEngine.git
上检出工程到本地时,起始目录叫做根目录。此外,开发过程中,为了方便起见,资源之间的引用是通过沙盒路径(虚拟路径)来进行标识的。
根目录
图 1-1 根目录
根目录说明如下:
- Engine 引擎目录,包含构成引擎的所有源代码、内容等。
- Samples 样例资源。
- Templates 样例工程模块,创建新项目时可用的项目模板集合。
- Setup.bat 只需运行一次。
- 拉取引擎的三方依赖
- 安装引擎运行环境 - 执行EngineExtrasRedisten-usUE4PrereqSetup_x64.exe
- 引擎注册 - 执行UnrealVersionSelector.exe,让uproject可以被windows识别。
- GenerateProjectFiles.bat 用于生成引擎vs工程文件。
Setup 和 GenerateProjectFiles还有对应的 .sh 文件,作用与.bat相同,用于在Mac平台下是生成从xcode工程文件。.command是Mac平台下的一种快捷方式,可以支持双击打开,而不在命令行模式执行。
通用目录
一些子目录是在引擎和游戏项目目录之间通用的:
- Binaries - 包含可执行文件或编译期间创建的其他文件。
- Build
- Config
- Content
- DerivedDataCache
- Intermediate
- Saved
- Source - 包含引擎或游戏的所有源文件,包括引擎源代码、工具和游戏类等。
- Engine - Engine目录中的源文件组织结构如下:
- Developer
- Editor
- Programs
- Runtime
- Game
源码模块组织方式
游戏项目目录中的源文件按模块分组,一个模块一个目录。每个模块包含以下内容:
- Classes
- Private - 包含所有
.cpp
文件,包括游戏类实现文件和模块实现文件。 - Public
引擎Source模块
图 1-2 EngineSource
引擎Source目录下分为以下目录:
- Developer
- Editor
- Programs
- Runtime
- ThirdParty
模块依赖原则
- Runtime 模块不能依赖 Editor或者Developer中的模块
- Plug-in 模块不能依赖其他Plug-ins
不同类型应用程序的模块使用样例
基础模块(新手)
- Core
- CoreUObject
- Engine
- OnlineSubsystem
- Slate
其他几个有趣模块(进阶)
- DesktopPlatform – Useful APIs for Windows, Mac & Linux
- DetailCustomizations – Editor’s Details panel customizations
- Launch – Main loop classes & functions
- Messaging – Message passing sub-system
- Sockets – Network socket implementations
- Settings – Editor & Project Settings API
- SlateCore – Fundamental UI functionality
- TargetPlatform – Platform abstraction layer
- UMG – Unreal Motion Graphics implementation
- UnrealEd – Unreal Editor main frame & features
- Analytics – Collects usage statistics from Editor & games
- AssetRegistry – Database for assets in Unreal Editor
- GameLiveStreaming – Twitch Streaming
- HeadMountedDisplay – HMD Support API (Oculus, etc.)
- JsonUtilities & XmlParser
- SourceControl
特定于引擎的目录
图 1-3 Engine引擎目录
部分子目录特定于Engine目录。
- Documentation - 包含引擎文档,包括源文件和发布的文件。
- HTML
- Source
- Extras
- Plugins
- Programs
- Shaders - 保存引擎的着色器源文件(
.usf
)。
游戏项目目录
图 1-4 游戏项目目录
- Binaries
- Config
- Content
- Plugins
- Intermediate
- Saved
- Source
- EasyUE4.sln
- EasyUE4.uproject
- EasyUE4.vs.db
Plugin插件目录
图 1-5 Plugin插件目录
- Binaries
- Content
- Intermediate
- Resources - 插件额外资源目录,如插件图标。
- ThirdParty - 插件依赖的三方库目录。
- ScriptPlugin.uplugin 插件文件,包含这个文件的目录会被UE4识别为一个插件目录。
沙盒路径
当我们在编辑器状态下浏览资源时,显示的资源路径,通常是沙盒路径
图 1-6 沙盒路径
/Game/ThirdPerson/Meshes/LeftArm_StaticMesh
/Engine/Maps/Entry
其中 /Game 是一个虚拟路径,实际表示的是项目的 FPaths::ProjectContentDir() 。/Engine 也是一个虚拟路径,实际路径是引擎的 FPaths::EngineContentDir()。更多虚拟路径可以查阅源码[3]
K:UnrealEngineEngineSourceRuntimeCoreUObjectPrivateMiscPackageName.cpp
类 FLongPackagePathsSingleton 的定义。
内容浏览器视图选项勾选显示引擎内容操作如下所示:
图 1-7 内容浏览器显示引擎内容
图 1-8 内容浏览器切换至引擎目录
路径获取和操作API
#include "BlankProgram.h"
#include "RequiredProgramMainCPPInclude.h"
#include "Misc/Paths.h"
DEFINE_LOG_CATEGORY_STATIC(LogBlankProgram, Log, All);
IMPLEMENT_APPLICATION(BlankProgram, "BlankProgram");
INT32_MAIN_INT32_ARGC_TCHAR_ARGV()
{
GEngineLoop.PreInit(ArgC, ArgV);
UE_LOG(LogBlankProgram, Display, TEXT("Hello World"));
// 常用路径获取接口
UE_LOG(LogBlankProgram, Display, TEXT("EngineDir: %s"), *FPaths::EngineDir());
UE_LOG(LogBlankProgram, Display, TEXT("EngineSavedDir: %s"), *FPaths::EngineSavedDir());
UE_LOG(LogBlankProgram, Display, TEXT("EngineIntermediateDir: %s"), *FPaths::EngineIntermediateDir());
UE_LOG(LogBlankProgram, Display, TEXT("ProjectDir: %s"), *FPaths::ProjectDir());
UE_LOG(LogBlankProgram, Display, TEXT("ProjectContentDir: %s"), *FPaths::ProjectContentDir());
UE_LOG(LogBlankProgram, Display, TEXT("ProjectConfigDir: %s"), *FPaths::ProjectConfigDir());
UE_LOG(LogBlankProgram, Display, TEXT("ProjectSavedDir: %s"), *FPaths::ProjectSavedDir());
UE_LOG(LogBlankProgram, Display, TEXT("ProjectIntermediateDir: %s"), *FPaths::ProjectIntermediateDir());
FString TestFilename(TEXT("ParentDirectory/Directory/FileName.extion"));
FString Extension = FPaths::GetExtension(TestFilename);
FString BaseFilename = FPaths::GetBaseFilename(TestFilename);
FString CleanFilename = FPaths::GetCleanFilename(TestFilename);
FString Directory = FPaths::GetPath(TestFilename);
bool bFileExists = FPaths::FileExists(TestFilename);
bool bDirectoryExists = FPaths::DirectoryExists(Directory);
UE_LOG(LogBlankProgram, Display, TEXT("TestFilename: %s"), *TestFilename);
// 获取文件扩展名
UE_LOG(LogBlankProgram, Display, TEXT("Extension: %s"), *Extension);
// 获取文件名,不带扩展名
UE_LOG(LogBlankProgram, Display, TEXT("BaseFilename: %s"), *BaseFilename);
// 获取文件名,带扩展名
UE_LOG(LogBlankProgram, Display, TEXT("CleanFilename: %s"), *CleanFilename);
// 获取路径文件夹,去除CleanFilename后的路径
UE_LOG(LogBlankProgram, Display, TEXT("Directory: %s"), *Directory);
// 检测文件是否存在
UE_LOG(LogBlankProgram, Display, TEXT("FileExists: %s"), bFileExists ? TEXT("True") : TEXT("False"));
// 检测文件夹是否存在
UE_LOG(LogBlankProgram, Display, TEXT("DirectoryExists: %s"), bDirectoryExists ? TEXT("True") : TEXT("False"));
// 路径拼接
FString NewFilePath = FPaths::Combine(Directory, TEXT("NewFilePath.txt"));
// 简便写法
FString NewFilePathEasy = Directory / TEXT("NewFilePath.txt");
// 相对路径转换为绝对路径
FString FullPath = FPaths::ConvertRelativePathToFull(FPaths::EngineDir());
UE_LOG(LogBlankProgram, Display, TEXT("NewFilePath: %s"), *NewFilePath);
UE_LOG(LogBlankProgram, Display, TEXT("NewFilePathEasy: %s"), *NewFilePathEasy);
UE_LOG(LogBlankProgram, Display, TEXT("FullPath: %s"), *FullPath);
return 0;
}
输出
LogBlankProgram: Display: Hello World
LogBlankProgram: Display: EngineDir: ../../../Engine/
LogBlankProgram: Display: EngineSavedDir: ../../../Engine/Saved/
LogBlankProgram: Display: EngineIntermediateDir: ../../../Engine/Intermediate/
LogBlankProgram: Display: ProjectDir: ../../../Engine/Programs/BlankProgram/
LogBlankProgram: Display: ProjectContentDir: ../../../Engine/Programs/BlankProgram/Content/
LogBlankProgram: Display: ProjectConfigDir: ../../../Engine/Programs/BlankProgram/Config/
LogBlankProgram: Display: ProjectSavedDir: ../../../Engine/Programs/BlankProgram/Saved/
LogBlankProgram: Display: ProjectIntermediateDir: ../../../Engine/Programs/BlankProgram/Intermediate/
LogBlankProgram: Display: TestFilename: ParentDirectory/Directory/FileName.extion
LogBlankProgram: Display: Extension: extion
LogBlankProgram: Display: BaseFilename: FileName
LogBlankProgram: Display: CleanFilename: FileName.extion
LogBlankProgram: Display: Directory: ParentDirectory/Directory
LogBlankProgram: Display: FileExists: False
LogBlankProgram: Display: DirectoryExists: False
LogBlankProgram: Display: NewFilePath: ParentDirectory/Directory/NewFilePath.txt
LogBlankProgram: Display: NewFilePathEasy: ParentDirectory/Directory/NewFilePath.txt
LogBlankProgram: Display: FullPath: K:/UnrealEngine/Engine/
参考
- ^目录结构 https://docs.unrealengine.com/zh-CN/Engine/Basics/DirectoryStructure/index.html
- ^FPaths https://docs.unrealengine.com/en-US/API/Runtime/Core/Misc/FPaths/index.html
- ^FPackageName https://docs.unrealengine.com/en-US/API/Runtime/CoreUObject/Misc/FPackageName/index.html