UE5.8 Game Features 喂饭级专题

UE5.8 Game Features 专题(四):GameFeatureAction 家族怎么选

讲清 UGameFeatureAction 生命周期、引擎内置 Action、AbilitySystemGameFeatureActions、Lyra 项目级 Action,以及每类 Action 的使用场景和清理责任。

总览

UGameFeatureAction 是 Game Feature 的执行单元。GameFeatureData 只是一张清单,Action 才是真正改变世界、组件、数据、UI、网络或调试工具的地方。

UE5.8 Game Features 专题(四):GameFeatureAction 家族怎么选 配图
Action 是玩法包真正改变项目的地方:加组件、加数据源、加地图内容、加作弊扩展、加网络过滤。

生命周期先记这个表

回调适合做什么注意
OnGameFeatureRegistering注册轻量数据、编辑器预览、路径登记不要加载大量运行时资产
OnGameFeatureLoading预备即将激活的资源处理软引用和 bundle
OnGameFeatureActivating(Context)把功能应用到世界最常写业务逻辑
OnGameFeatureActivated激活完成后通知不要做会失败的核心逻辑
OnGameFeatureDeactivating(Context)拆组件、拆输入、拆 UI、取消异步必须完整清理
OnGameFeatureUnloading释放加载期资源和 Loading 对称
OnGameFeatureUnregistering撤销注册期数据和 Registering 对称

引擎内置 Action 速查

Action适合
Add Components给 Pawn、Controller、GameState 等动态加组件
DataRegistry启用/停用整套 DataRegistry
DataRegistrySource给已有 Registry 添加 DataTable/CurveTable 来源
AddWorldPartitionContent / AddWPContent加载 World Partition 内容或 Content Bundle
AddCheats给 CheatManager 添加扩展
AddChunkOverride修改 Chunk 分配,用于打包/分发
Create Iris Network Filter给 Iris 注册网络过滤器
Add Attribute DefaultsAbilitySystemGameFeatureActions 里给 GAS 属性默认表

Lyra 的 Action 不全是引擎内置

Lyra 很适合学习,但要分清“引擎能力”和“项目实现”。例如 Lyra 的:

  • GameFeatureAction_AddAbilities
  • GameFeatureAction_AddInputContextMapping
  • GameFeatureAction_AddInputBinding
  • GameFeatureAction_AddWidget
  • GameFeatureAction_WorldActionBase

这些是 Lyra 项目代码,不是 GameFeatures 插件直接提供的通用类。你的项目可以照着思路写自己的版本。

使用案例:活动模式包

一个活动模式通常需要:

需求推荐 Action
给 PlayerState 加活动积分组件Add Components
加活动任务表/奖励表DataRegistrySource
给 HUD 加活动入口自定义 AddWidget Action
给玩家加活动技能自定义 AddAbilities Action 或 Lyra 风格
加活动地图区域AddWorldPartitionContent
内部测试命令AddCheats

不要把这些全写到一个超大 Action。一个 Action 做一种职责,停用清理才简单。

Data Validation 很重要

很多内置 Action 都实现了 IsDataValid,例如 Add Components 会检查 ActorClass 和 ComponentClass 是否为空,DataRegistrySource 会检查表类型和 Registry 名。你写自定义 Action 也应该做校验,因为 GameFeatureData 往往由策划或技术美术配置。

#if WITH_EDITOR
EDataValidationResult UGameFeatureAction_AddRifleUI::IsDataValid(FDataValidationContext& Context) const
{
    EDataValidationResult Result = Super::IsDataValid(Context);
    if (ReticleWidgetClass.IsNull())
    {
        Context.AddError(NSLOCTEXT("GameFeatures", "MissingReticle", "ReticleWidgetClass is missing."));
        Result = EDataValidationResult::Invalid;
    }
    return Result;
}
#endif

架构分析

Action 的重点不是“能打开”,而是“能关干净”。任何在 Activating 里注册的东西,都必须在 Deactivating 或 Unregistering 里撤销。注册 delegate 要保存 handle;添加组件要保存 request handle;创建 UI 要保存 widget handle;授予 Ability 要保存 spec handle;添加 Mapping Context 要保存玩家和 context 关系。

如果你找不到停用时怎么清理,说明这个逻辑可能不适合 Game Feature,或者需要先补一层可撤销接口。

常见坑

  • 把所有功能塞进一个巨型 Action,停用时不知道哪些东西来自哪里。
  • 只实现 OnGameFeatureActivating() 老接口,忘记新接口带 Context,更难处理多世界。
  • 在 Registering 阶段同步加载大量资产,导致启动卡顿。
  • 自定义 Action 注册 delegate 后不保存 handle,Deactivate 无法解绑。
  • 把 Lyra 的类名写进自己的文章/项目,却没把 Lyra 代码移植过来。

源码依据

UGameFeatureAction 定义了 Registering、Loading、Activating、Activated、Deactivating、Unloading、Unregistering。引擎内置 Action 分布在 GameFeatures/Public,例如 AddComponents、DataRegistry、DataRegistrySource、AddWorldPartitionContent、AddCheats、AddChunkOverride、IrisFilterGameFeatureAction。AbilitySystemGameFeatureActions 插件提供 UGameFeatureAction_AddAttributeDefaults

源码路径索引

  • GameFeatures/Public/GameFeatureAction.h
  • GameFeatures/Public/GameFeatureAction_AddComponents.h
  • GameFeatures/Public/GameFeatureAction_DataRegistry.h
  • GameFeatures/Public/GameFeatureAction_DataRegistrySource.h
  • GameFeatures/Public/GameFeatureAction_AddWorldPartitionContent.h
  • GameFeatures/Public/GameFeatureAction_AddCheats.h
  • GameFeatures/Public/IrisFilterGameFeatureAction.h
  • Experimental/AbilitySystemGameFeatureActions/Public/GameFeatureAction_AddAttributeDefaults.h