4.1 uplugin 与打包:版本、依赖与分发

插件的打包形态

形态 说明 分发方式
源码插件 源代码 + 资源,随项目编译 git / 项目 Plugins 目录
预编译插件(Binaries 已构建) 带对应引擎版本二进制 直接拷贝
市场插件(.upack) 打包后的安装单元 UE Marketplace / 本地安装

内部团队工具推荐「源码插件 + 项目 Plugins 目录 + git 版本管理」——编译问题最少,升级时改代码也直接。市场分发才需要 .upack。

版本号策略

uplugin 里有 Version(整数)和 VersionName(字符串)。我的规范:

  • Version:每次内容变更 +1,用于自动化检查「插件比项目里装的新还是旧」
  • VersionName:语义化版本 主.次.修,写给人看

跨引擎版本兼容是大问题。要点:

  1. 引擎版本写进 SupportedPrograms/或说明:uplugin 默认兼容多个引擎版本,但实际行为以构建为准。明确支持哪个版本写在描述里。
  2. 预编译插件必须带 Binaries:给别人的插件,对方不编译你的源码就必须有对应引擎版本(以及对应平台)的 Binaries 目录。
  3. 不要混装不同引擎版本的 Binaries:拷贝插件升级时清掉旧的 Binaries 目录,否则 UBT 可能用错。

打包成 .upack

插件目录 → 右键 → Package Plugin(或 Asset Manager 里的命令)

选择目标平台(Win64/Mac/Android…)后,UnrealFrontend/项目里生成 .upack,用户双击或通过「项目 → 插件 → 从文件安装」导入。分发时的检查清单:

  • [ ] 插件里的内容资源是否齐全(图标、模板、默认配置)
  • [ ] 是否依赖了项目专属内容(分发版必须自包含)
  • [ ] 测试:新项目装上插件,编译通过、无警告洪水
  • [ ] README/描述里写清楚:支持引擎版本、用法、示例

依赖与加载顺序

插件模块可以依赖其他插件(Market买的插件、引擎内置插件):

// Build.cs
PublicDependencyModuleNames.AddRange(new string[] { "CoreUObject", "Engine" });
PrivateDependencyModuleNames.AddRange(new string[] { "SomeOtherPlugin" });

挂了依赖之后,加载顺序由 UBT 推断——但循环依赖(A 依赖 B,B 依赖 A)直接编译失败。跨插件复杂依赖时,用 LoadingPhase 把自己延后(PostEngineInit 是最安全的默认值)。

插件升级的痛

插件随引擎大版本升级时,API 变动会集中爆发。降低痛苦的三个机制:

  1. 宏隔离引擎版本差异:#if ENGINE_MAJOR_VERSION==5 && ENGINE_MINOR_VERSION>=2 这类的条件编译
  2. 薄适配层:把引擎差异 API 封装成一个内部 helper,业务代码只调 helper
  3. CI 跨版本编译:对每个支持的引擎版本跑一次编译(见 5.4)

卸载与清理

发布给别人的插件要提供「干净卸载」:

  • 插件里的资产被项目中用了,卸载会引用丢失——提供「清理/迁移」工具或警告
  • uplugin 里的引擎配置(.ini 补充)很难自动撤销,写文档说明

心得:内部插件最容易死在「升级时没人维护」。推荐每个插件配个负责人写进 uplugin 的 CreatedBy/Description,升级窗口(引擎大版本升级)集中处理——插件没有主人的,升级时基本被弃用。