插件Plugin:
本来应该是指一种纯以接口与外界打交道的程序模块,在同一接口背后可以有多种实现,更换实现完全不影响客户端代码(不用重编)。
但是在ue4的世界里,插件似乎不是这个意思,仅仅是一种可以在构建时选择是否启用的模块,在客户端代码里充斥着对插件内部函数的调用
只不过这些调用一般要被封装在简单的#if WITH_PLUGINXXX之类的宏里
在构建时,若检测到插件未启用或不存在,就不会定义相应的宏,于是插件本身不被编译,调用它的代码也被清除,各自都相安无事。
插件描述符,在ubt里对应类PluginDescriptor,也就是每个插件目录里的*.uplugin文件
在其中定义了适用的平台、包含的模块、加载的时机等重要信息,一个插件可以包含多个模块,每个模块又可用于不同的目的
如ScriptPlugin这个插件,有3个模块,一个用于runtime,一个用于editor,还有一个用于unrealheadertool(没错,unrealheadertool也支持插件。。可以通过它生成更多的自定义代码)
{ "FileVersion" : 3, "Version" : 1, "VersionName" : "1.0", "FriendlyName" : "Script Plugin", "Description" : "An example of a script plugin. This can be used as a starting point when creating your own plugin.", "Category" : "Examples", "CreatedBy" : "Epic Games, Inc.", "CreatedByURL" : "http://epicgames.com", "DocsURL" : "", "MarketplaceURL" : "", "SupportURL" : "", "EnabledByDefault" : false, "CanContainContent" : false, "IsBetaVersion" : false, "Installed" : false, "CanBeUsedWithUnrealHeaderTool" : true, "Modules" : [ { "Name" : "ScriptGeneratorPlugin", "Type" : "Program", "LoadingPhase" : "PostConfigInit" }, { "Name" : "ScriptPlugin", "Type" : "Runtime", "LoadingPhase" : "PreDefault", "BlacklistPlatforms" : [ "Linux" ] }, { "Name" : "ScriptEditorPlugin", "Type" : "Editor", "LoadingPhase" : "Default", "BlacklistPlatforms" : [ "Linux" ] } ] }
另外,在这里也定义该插件是否默认启用【PluginDescriptor.bEnabledByDefault】,如启用的话就会自动包含在任何项目构建中。
而每个项目也可以明确定义了自己需要或屏蔽的插件【ProjectDescriptor.Plugins】,优先级高于前者。
再有就是项目里的每个Target还可以强制指定包含所有插件【TargetRules.bBuildAllPlugins】,优先级又高于前者。比如UE4Editor就强制启用了所有插件。
一旦一个插件决定参与构建,在后续的过程中(包括在运行时),它就跟一般的模块没什么区别了。
那插件和模块到底有什么不同呢?我觉得,就是插件可以方便的配置要不要编进来,而一般模块的依赖性是固定的,要了模块A就必须要模块B,不可能把A配置成可以动态的选择要不要B,因为如果可以的话,那B其实就是个插件了。