UGameFeatureAction
类
这是一个抽象基类,用于定义游戏功能模块激活时需要执行的具体操作。它在 LyraStarterGame 项目中被广泛用于模块化和插件化的游戏功能管理。
GameFeatureAction.h
// 版权所有 Epic Games, Inc. 保留所有权利。
#pragma once
#include "GameFeatureAction.generated.h"
#define UE_API GAMEFEATURES_API
class UGameFeatureData;
struct FGameFeatureActivatingContext;
struct FGameFeatureDeactivatingContext;
struct FAssetBundleData;
/**
* 定义在游戏功能激活过程中需要执行的具体行为
* 该基类提供了一系列生命周期回调,用于响应功能插件的不同状态变化
*/
UCLASS(MinimalAPI, DefaultToInstanced, EditInlineNew, Abstract)
class UGameFeatureAction : public UObject
{
GENERATED_BODY()
public:
/**
* 获取与当前操作关联的 GameFeatureData 实例
* 通过逐层查找外部对象链实现
*/
UE_API virtual UGameFeatureData* GetGameFeatureData() const;
/**
* 在所属的游戏功能被注册时调用
* 此时功能尚未激活,仅完成注册准备
*/
virtual void OnGameFeatureRegistering() {}
/**
* 当前操作即将被注销时触发
* 注销后除非重新注册,否则不会再次参与激活流程
*/
virtual void OnGameFeatureUnregistering() {}
/**
* 功能模块开始加载资源以准备激活时调用
* 可用于预加载相关数据或初始化依赖项
*/
virtual void OnGameFeatureLoading() {}
/**
* 游戏功能正在卸载资源时调用
* 应在此处清理运行时创建的内容
*/
virtual void OnGameFeatureUnloading() {}
/**
* 在功能实际进入激活阶段时调用
* 提供上下文信息用于处理动态绑定和条件判断
*/
UE_API virtual void OnGameFeatureActivating(FGameFeatureActivatingContext& Context);
/**
* 兼容旧版本的激活入口
* 若未重写带上下文的版本,则由基类自动调用此函数
*/
virtual void OnGameFeatureActivating() {}
/**
* 激活流程完全完成后调用
* 所有资源已加载,系统处于稳定状态
*/
virtual void OnGameFeatureActivated() {}
/**
* 功能即将停用时调用
* 可能会在未来重新激活,需保留必要状态
*/
virtual void OnGameFeatureDeactivating(FGameFeatureDeactivatingContext& Context) {}
/**
* 查询当前操作所属的游戏功能插件是否已完成注册
* @param bCheckForRegistering 是否包含正在注册中的状态
* @return true 表示已注册或正在注册中
*/
UE_API bool IsGameFeaturePluginRegistered(bool bCheckForRegistering = false) const;
/**
* 判断游戏功能插件当前是否处于活跃状态
* @param bCheckForActivating 是否将激活过程中的状态视为活跃
* @return true 表示插件处于活动状态
*/
UE_API bool IsGameFeaturePluginActive(bool bCheckForActivating = false) const;
#if WITH_EDITORONLY_DATA
/**
* 编辑器模式下添加额外的资源包数据
* 用于支持内容打包和构建系统识别依赖资源
* @param AssetBundleData 要填充的数据结构
*/
virtual void AddAdditionalAssetBundleData(FAssetBundleData& AssetBundleData) {}
#endif
};
#undef UE_API
GameFeatureAction.cpp
// 版权所有 Epic Games, Inc. 保留所有权利。
#include "GameFeatureAction.h"
#include "GameFeatureData.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(GameFeatureAction)
/**
* 查找并返回与此操作关联的 UGameFeatureData 对象
* 遍历对象外层容器直至找到匹配类型的实例
*
* @return 成功找到则返回有效指针,否则返回 nullptr
*/
UGameFeatureData* UGameFeatureAction::GetGameFeatureData() const
{
// 从当前对象的外部对象开始向上追溯对象层级
for (UObject* Obj = GetOuter(); Obj; Obj = Obj->GetOuter())
{
// 尝试将当前层级的对象转换为 UGameFeatureData 类型
if (UGameFeatureData* GFD = Cast<UGameFeatureData>(Obj))
{
/**
* 游戏功能激活时的处理函数(带上下文)
* 若派生类未重写此方法,则自动调用旧版无上下文参数的版本
* @param Context 激活过程中的上下文信息
*/
void UGameFeatureAction::OnGameFeatureActivating(FGameFeatureActivatingContext& Context)
{
// 如果子类没有覆盖当前方法,则回退至原始无参形式的激活逻辑
OnGameFeatureActivating();
}
/**
* 判断该操作所属的游戏功能插件是否已完成注册
* @param bCheckForRegistering 是否将“正在注册中”的状态也视为已注册
* @return 当插件已注册(或处于注册过程中,视参数而定)时返回 true;否则返回 false
*/
bool UGameFeatureAction::IsGameFeaturePluginRegistered(bool bCheckForRegistering /*= false*/) const
{
// 获取与此 Action 关联的 GameFeatureData 对象
UGameFeatureData* GameFeatureData = GetGameFeatureData();
// 若存在有效数据对象,则调用其注册状态检查函数,否则直接返回 false
return !!GameFeatureData ? GameFeatureData->IsGameFeaturePluginRegistered(bCheckForRegistering) : false;
}
/**
* 查询此操作所归属的游戏功能插件是否处于激活状态
* @param bCheckForActivating 是否将“正在激活中”的状态视为激活
* @return 若插件已激活(或正处于激活流程中,依据参数决定)则返回 true,反之为 false
*/
bool UGameFeatureAction::IsGameFeaturePluginActive(bool bCheckForActivating /*= false*/) const
{
// 获取关联的 GameFeatureData 实例
UGameFeatureData* GameFeatureData = GetGameFeatureData();
// 存在数据对象时委托查询,否则返回 false
return !!GameFeatureData ? GameFeatureData->IsGameFeaturePluginActive(bCheckForActivating) : false;
}
/**
* 成员变量说明(本类未显式声明成员变量)
*/
GENERATED_BODY()
// 解析:`UCLASS()` 是虚幻引擎的核心宏之一,用于启用反射系统支持。
// 它会自动生成必要的元数据,以实现序列化、蓝图访问、GC管理等功能。
// 虽然不是函数或变量,但它是类定义中不可或缺的部分。
应用说明:
所有继承自 `UGameFeatureAction` 的子类都将具备反射能力,
从而可以在编辑器中被可视化展示、通过蓝图调用、并参与持久化存储流程。
这是与UE4/UE5框架深度集成的基础要求。
UGameFeatureAction
/**
* 核心成员函数详细分析
*/
virtual UGameFeatureData* GetGameFeatureData() const
作用说明:
通过遍历当前对象的 Outer 链(外部容器链),向上查找并返回首个匹配类型的 `UGameFeatureData` 父级对象。
该机制确保每个 Action 能准确识别其所归属的功能模块。
Lyra项目中的典型用途:
在 LyraStarterGame 中,每一个 `UGameFeatureAction` 都作为子对象嵌入于某个具体的 `UGameFeatureData` 资产内。
当需要确定当前行为属于哪一个可插拔功能时(例如加载新武器、技能或游戏模式),
便可通过此函数定位其宿主插件数据,建立上下文关联。
Outer
UGameFeatureData
virtual void OnGameFeatureRegistering()
作用说明:
在包含该 Action 的 `GameFeatureData` 被注册到游戏系统时触发调用。
这是生命周期的第一个阶段,无论后续是否会实际激活该功能都会执行。
适合进行轻量级、一次性的初始化工作。
Lyra应用场景示例:
假设有一个用于注册新型 GameplayAbility 的 Action,
在此函数中可向全局能力系统注册该能力的 UClass 类型信息,
但暂不创建任何实例,避免资源浪费。
GameFeatureData
GameplayAbility
virtual void OnGameFeatureUnregistering()
作用说明:
当对应的 `GameFeatureData` 被注销时调用,用于逆向清理之前所做的注册操作。
保证系统的干净解耦和内存安全。
Lyra应用实例:
延续上述例子,在此方法中应从全局能力管理系统中移除先前添加的类注册项,
防止残留引用导致潜在错误或泄露。
OnGameFeatureRegistering
virtual void OnGameFeatureLoading()
作用说明:
表示该功能插件即将进入激活流程,系统开始加载相关资源包(如 Asset Bundles)时调用。
标志着功能激活流程的启动信号。
Lyra中的使用方式:
可用于预加载关键软引用资源(SoftObjectPtr)、启动异步加载任务,
或者触发 UI 提示用户“正在加载新内容”。
virtual void OnGameFeatureUnloading()
OnGameFeatureLoading
作用说明:
当功能插件被卸载、资源准备释放时调用。
提供一个最后的机会来清理已加载的资源或重置状态。
Lyra中的实践:
可在该函数中释放由 `OnGameFeatureRegistering` 或 `OnGameFeatureActivating` 所持有的资源,
比如卸载预加载的纹理、音效或其他资产,确保资源及时归还给引擎。
virtual void OnGameFeatureActivating(FGameFeatureActivatingContext& Context)
作用说明:
作为核心执行函数,负责实现具体的功能变更逻辑。
通常在功能正式激活后调用,是大多数 Action 真正“生效”的时刻。
当功能插件被正式激活并开始对游戏世界产生影响时,会调用该函数。参数
Context
提供了激活时的上下文信息(例如目标世界)。如果派生类未重写此带有上下文的版本,基类将自动调用下方无参数的替代版本。
Lyra 应用示例:
GameFeatureAction_AddWidget
在此处为本地玩家创建并添加一个 HUD 组件。
GameFeatureAction_AddComponents
针对符合特定条件的 Actor(通过数据资产进行筛选),动态附加新的组件,例如技能系统或属性管理组件。
GameFeatureAction_DataRegistry
加载指定的数据表格,并将其注册到全局数据注册表中,供游戏运行时查询使用,如武器属性、角色基础数值等。
旧式激活方法(无上下文): 为保持向后兼容性而保留。现代开发中建议优先使用带上下文参数的版本。
virtual void OnGameFeatureActivating()
Lyra 中的应用: 新的 Action 类通常不再使用此无参版本,因为带上下文的版本能够明确区分激活环境(客户端/服务器、主世界/流式加载的世界),从而提升逻辑准确性。
插件就绪回调: 当功能插件完成全部激活流程并进入就绪状态时调用。标志着插件已完全上线。
virtual void OnGameFeatureActivated()
Lyra 应用场景: 可在此执行仅在激活完成后才可进行的操作,比如广播事件通知其他系统“新武器类型现已可用”,或与在
OnGameFeatureActivating
中添加的组件进行首次交互和初始化。
停用处理函数: 在功能插件被关闭或移除时触发,用于撤销
OnGameFeatureActivating
中所做的一切变更。参数
Context
提供停用时的上下文信息。
Lyra 实践应用: 此处是资源清理的核心位置,常见操作包括:
- 移除之前添加的 HUD 组件;
- 销毁动态附加至 Actor 的组件;
- 从数据注册表中注销相关数据表格。
virtual void OnGameFeatureDeactivating(FGameFeatureDeactivatingContext& Context)
插件注册状态查询: 检查当前 Action 所属的插件是否已被注册到引擎系统。若参数
bCheckForRegistering
设为 true,则即使处于正在注册过程中的状态,也会返回 true。
Lyra 使用方式: 可用于 Action 内部逻辑的条件控制,例如“仅当插件已注册时才允许执行某段初始化代码”,防止在非法状态下误操作。
bool IsGameFeaturePluginRegistered(bool bCheckForRegistering = false) const
插件活动状态检查: 判断所属插件是否当前处于激活状态。参数
bCheckForActivating
若为 true,则激活过程中的状态也视为有效。
Lyra 应用实例: 可供 Action 自身或其他外部系统进行运行时状态判断。例如,某个游戏机制需确认“突击步枪插件是否已激活”,以决定是否生成对应武器或显示相关 UI 界面。
bool IsGameFeaturePluginActive(bool bCheckForActivating = false) const
编辑器模式专用功能: (仅限编辑器环境下调用)允许 Action 向其所属的
UGameFeatureData
资产中添加额外的引用资产列表。这些引用将被打包进插件对应的资产包中,实现声明式的依赖管理。
Lyra 实际用途: 若某个
GameFeatureAction
需要依赖特定材质或音效资源,可在本函数中将这些资源路径添加至
AssetBundleData
中。这样在打包插件时,系统会自动包含这些依赖项,确保运行时能正确加载,避免手动维护资源依赖关系。
virtual void AddAdditionalAssetBundleData(FAssetBundleData& AssetBundleData)
总结:与 Lyra 项目架构的关系
在 LyraStarterGame 项目中:
UGameFeatureData
作为一个数据资产存在,代表一个可插拔的游戏功能模块,例如“狙击枪套装”或“夺旗模式”。
每个
UGameFeatureData
资产内部包含一个
UGameFeatureAction
对象的数组。
其中,
UGameFeatureAction
是整个架构中的“可执行单元”。每一个具体的派生类负责一项独立且可复用的任务,如添加组件、绑定输入映射、注册数据资源等。
Lyra 通过将不同的
UGameFeatureAction
组合配置到一个
UGameFeatureData
中,来定义完整功能模块的行为逻辑。这种设计实现了高度的解耦与可配置性——新增功能就如同在数据资产中勾选几个 Action 并进行设置,无需改动核心 C++ 代码即可完成扩展。


雷达卡


京公网安备 11010802022788号







