打包后程序会加载Editor下的Plugin

整个的流程如下:(任何项目都可以重现)

  1. Build MyTestProject项目,生成Development(Test和Shipping下target也都有这些Plugin)版本,使用UBT生成exe,pdb,target等文件。

<br/>

[Image Removed]

[Image Removed]

2.cook生成Staging文件的时候,根据target文件生成upluginmanifest文件。

<br/>

3.最终upluginmanifest文件会被Pak到Package中,在运行时根据这个文件加载Plugin。

<br/>

按照我的理解,既然Plugin的类型被标记为Editor,就不应该在最终的包中出现。所以需要在UBT中,编译的时候对Type进行判断 ,比如在下边的相关代码中调用Plugins.IsPluginCompiledForTarget,来判断是否应该使用该Plugin。

[Image Removed]

重现步骤

使用Sample中的任何Project都可以。

在最终打包后的游戏中,发现Editor下的Plugin也会被加载。(虽然这些Plugin的类型是Editor,但依然会被加载)

您好,这些插件的uplugin文件中,并没有显式的标注是Editor的,因此也会被include到启用的插件列表中

但是编译的时候是会判断插件中 module 的 type 是否是 game/Runtime 的,因此相关的代码不会被编译进打包输出的exe中(实际上也就没有加载)

您好,可以搜下 MyTestProject.exe.rsp 文件,里面描述了所有链接进exe的模块,并对比过滤和不过滤的情况。

我觉得不是这类标记了Editor的Module引起的exe减小,但是有减小这个事情确实挺重要的

【还有UBT为什么不能区分是否是EditorOnly的Module呢?】 这里是不是说错了,是EditorOnly的插件吧?

理论上也是可以的,不过根据uplugin里的module其实是间接地获取,不是直接的标记。

由于目前已经将Editor的Module排除出去了,这里应该说是没有做的非常细致,没将未编译的uplugin也排除出去。

如果非常介意这个target文件里出现的uplugin文件,我看了一下一个简单的改法:

// 找到 Engine\Source\Programs\UnrealBuildTool\Configuration\UEBuildTarget.cs, 将 BuildPlugins = new List<UEBuildPlugin>(NameToInstance.Values); // 修改为 BuildPlugins = new List<UEBuildPlugin>(NameToInstance.Values.Where( x => x.Modules.Count() > 0) );然后在MyTestProject.Target.cs中,写入

bRuntimeDependenciesComeFromBuildPlugins = true;

[Image Removed]比如这个插件,ContentBrowserAssetDataSource,Type显式指定为Editor,但会在Shipping.target中出现。

当把这些plugin在UBA中通过条件过滤掉,编译出来的exe会小十几M,所以这些代码应该是会编译到exe中。

MyTestProject.exe.rsp 文件里确实没有看到这些模块相关的文件,但编译后的.target文件里有这些文件,以及cook后生成的upluginmanifest文件里都显示的有这些plugin就很奇怪了。并且加载时候直接读取的upluginmanifest文件。(Test和Development都确认是这样的流程,Shipping下还没来的及测试。)

target里包含是符合预期的,UBT在编译的过程中只是过滤Editor的module,而不是过滤plugin

例如有些plugin里面又有Runtime的,又有Editor的​模块,那么编译的时候只会包含runtime的module,比如paper2D.uplugin

最主要的原因是UBT无法区分哪些插件是editor only的,只有在uproject或uplugin中引用的plugin字段里,标记了TargetAllowList的uplugin才会被直接过滤掉

"Plugins": [ { "Name": "XXX", "Enabled": true, "TargetAllowList": [ "Editor" ] } ]

好的,多谢!

如果这些类型的Plugin(确切的说是这些Plugin中的Module)只是在.target中出现,而没有进入.exe也是没有问题的。

我再先查找一下,为什么屏蔽这些Module后,exe会变小。(在UBT中我也只是屏蔽的Module(Type为Editor类型的Module),而不是整个Plugin都屏蔽掉)

还有UBT为什么不能区分是否是EditorOnly的Module呢?进入UBT的时候,Target以及Platform这些都是已知的,并且在uplugin里也显式的指定了Module的Type类型。

比如这个插件(ContentBrowserAssetDataSource)这个插件里只有一个Module,并且指定了这个Module的Type为Editor。一个插件有多个Module是没问题的,每个Module的Type都显式的指定了自己的Type,这些在UBT中都可以获取到的。[Image Removed]

好的,非常感谢!

确实这些Plugin只是名字出现在了Target中,而代码并没有链接到最终的exe中。

通过对比,我发现我之前的修改有问题,导致了两次编译出来的exe大小会相差十几M。在UEBuildTarget.cs中,AddPlugin的时候,通过Plugins.IsPluginCompiledForTarget来进行判断,会误杀掉某些Module(比如:EOSSDK-Win64-Shipping.dll, 由于我测试的Test版本,所以会认为这种Module不符合该Target),这种类型的Module被杀掉后,短时间内在游戏中测试没发现任何问题,我误认为了是由于Editor类型的Plugin导致的。

在运行时,这些Editor类型的Plugin虽然会进入FPluginManager中的PluginsArray,并调用了Context.Load(*Plugin.Name),但并不会实质的Load。

优雅的改法确实需要你上边这种修改方法,通过这种修改,前后对比发现,编译出来的exe只减少了27k(修改前exe Size:256370KB,修改后exe Size:256343KB)的大小,这样来看,确实没太大修改的必要。

再次的表示感谢,谢谢!