总览
Game Feature 插件有两个核心入口:.uplugin 和 UGameFeatureData。.uplugin 是“系统怎么认识这个玩法包”,GameFeatureData 是“这个玩法包激活时做哪些动作”。这两个没设计好,后面 Action 写得再漂亮也会难维护。
.uplugin 的关键字段
| 字段 | 建议 | 含义 |
|---|---|---|
CanContainContent | true | 大多数玩法包要放资产 |
EnabledByDefault | false | 不让普通插件系统直接启用全部内容 |
ExplicitlyLoaded | true | 由 Game Feature 流程显式加载 |
BuiltInInitialFeatureState | Registered/Loaded/Active | 启动时自动推进到哪个状态 |
Plugins | 明确写依赖 | 例如 GameFeatures、ModularGameplay、GAS、CommonUI |
UE5.8 源码里 DetermineBuiltInInitialFeatureState 支持四个值:Installed、Registered、Loaded、Active。如果没有新字段,会回退到老的 BuiltInAutoRegister/BuiltInAutoLoad/BuiltInAutoActivate。
四种初始状态怎么选
| 状态 | 适合 |
|---|---|
Installed | 包存在,但启动时不注册,适合真正按需发现的内容 |
Registered | 启动时进入可加载状态,适合大多数内置玩法包 |
Loaded | 资源和代码准备好,但不激活,适合马上要用但要等玩法条件的包 |
Active | 开局就启用,适合基础模式或必备体验 |
初学建议用 Registered。它不会一启动就把所有 Action 执行掉,但 LoadGameFeaturePlugin PluginName 能直接测试。
GameFeatureData 里有什么
UGameFeatureData 继承 UPrimaryDataAsset,它有两个重点字段:
| 字段 | 用途 |
|---|---|
Actions | 激活、停用时要执行的动作列表 |
PrimaryAssetTypesToScan | 告诉 Asset Manager 这个插件里有哪些 Primary Asset 类型要扫描 |
Action 是 instanced UObject,编辑器里可以直接在 GameFeatureData 的数组里加 Add Components、DataRegistry、WP Content、项目自定义 Action。
推荐目录结构
Plugins/GameFeatures/WeaponPack_Rifle/
Config/
Tags/WeaponPack_RifleTags.ini
Content/
DA_GameFeatureData_Rifle
Weapons/DA_RifleWeapon
Input/IMC_Rifle
UI/WBP_RifleReticle
Abilities/GA_RifleFire
Source/
WeaponPack_RifleRuntime/
Public/
Private/
WeaponPack_Rifle.uplugin
命名上把插件名、资产名前缀、GameplayTag 前缀保持一致。比如 Feature.Weapon.Rifle、Input.Weapon.Rifle.Fire、UI.Weapon.Rifle.Reticle。
插件 Config 怎么用
UGameFeatureData 有 InitializeBasePluginIniFile 和 InitializeHierarchicalPluginIniFiles。这意味着 Game Feature 插件可以带配置文件,并在加载/激活阶段合入配置。适合放 GameplayTags、DataRegistry、平台差异、项目自定义设置。
不要把主工程必须存在的基础配置放在可选 Game Feature 插件里。否则插件未注册时,主工程启动就可能缺 Tag 或缺类。
使用案例:赛季活动包
一个赛季活动包可以这样拆:
.uplugin:BuiltInInitialFeatureState=Registered,上线后由服务器配置决定是否激活。- GameFeatureData Actions:Add Components 给 PlayerController 加活动任务追踪组件;Add DataRegistry Source 加活动奖励表;Add UI Widget 加活动入口。
- PrimaryAssetTypesToScan:扫描活动任务、奖励、活动商店商品。
- Config Tags:声明
Event.Season12.*。
活动结束时停用插件,输入/UI/组件/数据源都应该跟着拆掉。
架构分析
.uplugin 是包级元数据,适合描述依赖、初始状态和加载策略;GameFeatureData 是玩法级数据,适合描述激活时要执行的动作;PrimaryAssetTypesToScan 是资源发现协议,适合把插件里的玩法定义交给 Asset Manager。三者不要互相替代:不要把运行时行为写进 .uplugin,也不要让 Action 临时扫描一堆未登记资源。
常见坑
EnabledByDefault=true又希望运行时控制启停,语义冲突。Active玩法包里放大量非启动必要资源,首帧加载变慢。- 所有玩法包都依赖彼此,最后没有一个能独立测试。
- Primary Asset 类型散在主工程和插件之间,Cook 时找不到资源。
- 插件 Config 里声明了主工程启动必须依赖的 Tag,导致插件关闭后主工程不完整。
源码依据
UGameFeatureData 继承 UPrimaryDataAsset,有 Actions 和 PrimaryAssetTypesToScan。UGameFeaturesSubsystem::DetermineBuiltInInitialFeatureState 在 UE5.8 中优先读取 BuiltInInitialFeatureState,支持 Installed、Registered、Loaded、Active,并保留老字段兼容。Lyra 的 ShooterCore 插件使用 ExplicitlyLoaded=true 和 BuiltInInitialFeatureState=Registered,是很好的项目参考。
源码路径索引
GameFeatures/Public/GameFeatureData.hGameFeatures/Private/GameFeaturesSubsystem.cppGameFeatures/Private/GameFeatureData.cppGameFeatures/Public/GameFeaturesSubsystemSettings.hSamples/Games/Lyra/Plugins/GameFeatures/ShooterCore/ShooterCore.uplugin