UE4 关于工程目录结构的一个小技巧

UE4 的工程都会有一个以 .uproject 为后缀的工程描述文件,这个文件里会记录模块信息,插件信息等,还有一个与该项目关联的引擎信息,如图所示

uproject.png

EngineAssociation 字段记录的是一个注册表键值,对应引擎的根目录路径,表示这个工程使用的是这个路径的引擎,如图

reg.png

问题

这里就存在一个问题,因为 uproject 文件是需要提交到代码库里版控的,所以当项目里的其它人如美术,策划打开游戏工程时,这个字段会被修改为自己本地引擎对应的注册表键值,当这个文件被不小心提交到库里,或者因为打开关闭了某个插件必须将 uproject 提交到库里的时候,就会影响到整个项目组,其他人更新这个文件的时候需要重新切换一下引擎

观赏一下这个文件被 checkout 的盛况 : )

uproject_checkout.png

虽然这是个小问题,只需要 switch 引擎即可,但是如果有办法解决,那就一劳永逸了

解决方法

当我们运行引擎的 GenerateProjectFiles 脚本生成工程的时候,其实 UnrealBuildTools 同时还会根据引擎根目录下的 UE4Games.uprojectdirs 文件中的记录的路径去查找(相对搜索深度最多1层)具有 .uproject 文件的游戏工程,并将这些游戏工程一起加入到整个 sloution 中,相关代码见 Engine/Source/Programs/UnrealBuildTool/System/NativeProjects.cs 中的 EnumerateBaseDirectoriesEnumerateProjectFiles 函数

因此我们可以在引擎根目录下类似 SamplesTemplates 新建一个子目录 Games 专门用来放游戏工程,并将这个目录添加到 UE4Games.uprojectdirs 文件中,如图

uprojectdirs.png

然后新建游戏工程到这个目录下(或者将已有的游戏工程库拉到这个目录下),重新运行 GenerateProjectFiles 生成解决方案,最终的 solution 结构如图

solution.png

目录结构如图

root.png

games.png

而这时,新建到这个路径下的项目的 uproject 文件中的 EngineAssociation 是空的,如图

uproject_new.png

而且直接双击 uproject 文件可以直接打开工程,无需选择引擎(因为这时会使用上层目录中的引擎来打开游戏工程,或者如果是老工程可以直接将 EngineAssociation 置空),此时将 uproject 文件提交到库里,就不会因为 EngineAssociation 导致冲突了

总结

这个方法有两个好处

  1. 防止 EngineAssociation 字段改动污染整个项目组
  2. 将同一个引擎的相关游戏工程都组织到一起,可以共享一个解决方案,方便做测试