Lyra Starter Game 中 GameFeature 类(如 ShooterCore)的加载流程

Lyra Starter Game 中 GameFeature 类(如 ShooterCore)的加载流程

1. GameFeature 系统概述

GameFeature 是 Unreal Engine 5 的一个核心插件系统,用于模块化地扩展游戏功能。在 Lyra Starter Game 中,ShooterCore 是一个典型的 GameFeature 插件,它提供了射击游戏的核心玩法系统。

2. GameFeature 核心组件

2.1 UGameFeatureData 类

UGameFeatureData 是 GameFeature 的核心数据资产类,定义在引擎的 GameFeatures 插件中:

cpp 复制代码
// 定义在 C:\UnrealEngine-5.6.1-release\Engine\Plugins\Runtime\GameFeatures\Source\GameFeatures\Public\GameFeatureData.h
UCLASS(MinimalAPI)
class UGameFeatureData : public UPrimaryDataAsset
{
    GENERATED_BODY()
    
    // 游戏特性的主要行为定义
    UPROPERTY(EditDefaultsOnly, Instanced, Category="Game Feature | Actions")
    TArray<TObjectPtr<UGameFeatureAction>> Actions;
    
    // 需要扫描的主资产类型
    UPROPERTY(EditAnywhere, Category="Game Feature | Asset Manager")
    TArray<FPrimaryAssetTypeInfo> PrimaryAssetTypesToScan;
};

2.2 UGameFeatureAction 类

UGameFeatureAction 是 GameFeature 的具体行为实现,每个 GameFeatureData 包含多个 Action,用于执行特定功能:

  • GameFeatureAction_AddAbilities:添加游戏能力
  • GameFeatureAction_AddInputBinding:添加输入绑定
  • GameFeatureAction_AddWidget:添加 UI 控件
  • GameFeatureAction_AddGameplayCuePath:添加游戏玩法提示路径

3. ShooterCore 插件结构

ShooterCore 插件是一个典型的 GameFeature 插件,其结构如下:

复制代码
ShooterCore/
├── Content/
│   └── ShooterCore.uasset      # GameFeatureData 配置文件
├── Source/
│   └── ShooterCoreRuntime/     # 运行时代码
│       ├── Private/            # 私有实现
│       └── Public/             # 公共接口
└── ShooterCore.uplugin         # 插件描述文件

4. GameFeature 加载流程

4.1 插件注册阶段

  1. 插件发现:引擎启动时,会扫描所有已启用的 GameFeature 插件
  2. GameFeatureData 加载:为每个 GameFeature 插件加载其 GameFeatureData 配置文件(如 ShooterCore.uasset)
  3. 观察者通知 :调用所有观察者的 OnGameFeatureRegistering 方法

Lyra 项目中,ULyraGameFeature_AddGameplayCuePaths 是一个观察者,用于在注册阶段添加 GameplayCue 路径:

cpp 复制代码
// 定义在 LyraGameFeaturePolicy.cpp
void ULyraGameFeature_AddGameplayCuePaths::OnGameFeatureRegistering(const UGameFeatureData* GameFeatureData, const FString& PluginName, const FString& PluginURL)
{
    for (const UGameFeatureAction* Action : GameFeatureData->GetActions())
    {
        if (const UGameFeatureAction_AddGameplayCuePath* AddGameplayCueGFA = Cast<UGameFeatureAction_AddGameplayCuePath>(Action))
        {
            // 添加 GameplayCue 路径
            const TArray<FDirectoryPath>& DirsToAdd = AddGameplayCueGFA->GetDirectoryPathsToAdd();
            if (ULyraGameplayCueManager* GCM = ULyraGameplayCueManager::Get())
            {
                for (const FDirectoryPath& Directory : DirsToAdd)
                {
                    FString MutablePath = Directory.Path;
                    UGameFeaturesSubsystem::FixPluginPackagePath(MutablePath, PluginRootPath, false);
                    GCM->AddGameplayCueNotifyPath(MutablePath, false);
                }
                // 重新构建运行时库
                GCM->InitializeRuntimeObjectLibrary();
            }
        }
    }
}

4.2 插件加载阶段

  1. 依赖检查:检查插件的依赖是否已满足
  2. 资源预加载:根据 GameFeatureData 配置预加载所需资源
  3. 观察者通知 :调用所有观察者的 OnGameFeatureLoading 方法

Lyra 项目中,ULyraGameFeature_HotfixManager 是一个观察者,用于在加载阶段处理热修复:

cpp 复制代码
// 定义在 LyraGameFeaturePolicy.cpp
void ULyraGameFeature_HotfixManager::OnGameFeatureLoading(const UGameFeatureData* GameFeatureData, const FString& PluginURL)
{
    if (ULyraHotfixManager* HotfixManager = Cast<ULyraHotfixManager>(UOnlineHotfixManager::Get(nullptr)))
    {
        HotfixManager->RequestPatchAssetsFromIniFiles();
    }
}

4.3 插件激活阶段

  1. Action 激活 :遍历 GameFeatureData 中的所有 GameFeatureAction,调用它们的 OnGameFeatureActivating 方法
  2. 世界集成:将 GameFeature 集成到当前游戏世界中
  3. 观察者通知 :调用所有观察者的 OnGameFeatureActivating 方法

GameFeatureAction_AddAbilities 为例,它会在激活时为指定的 Actor 类添加能力:

cpp 复制代码
// 定义在 GameFeatureAction_AddAbilities.cpp
void UGameFeatureAction_AddAbilities::OnGameFeatureActivating(FGameFeatureActivatingContext& Context)
{
    FPerContextData& ActiveData = ContextData.FindOrAdd(Context);
    
    if (!ensureAlways(ActiveData.ActiveExtensions.IsEmpty()) || 
        !ensureAlways(ActiveData.ComponentRequests.IsEmpty()))
    {
        Reset(ActiveData);
    }
    Super::OnGameFeatureActivating(Context);
}

4.4 插件运行阶段

GameFeature 激活后,其定义的功能(如能力、输入、UI 等)将在游戏中生效。

4.5 插件停用阶段

  1. Action 停用 :遍历 GameFeatureData 中的所有 GameFeatureAction,调用它们的 OnGameFeatureDeactivating 方法
  2. 资源清理:清理 GameFeature 使用的资源
  3. 观察者通知 :调用所有观察者的 OnGameFeatureDeactivating 方法

4.6 插件卸载阶段

  1. 资源卸载:卸载 GameFeature 使用的资源
  2. 插件移除:从系统中移除 GameFeature
  3. 观察者通知 :调用所有观察者的 OnGameFeatureUnregistering 方法

5. ShooterCore 插件的具体加载流程

5.1 插件描述文件

ShooterCore.uplugin 定义了插件的基本信息和依赖:

json 复制代码
{
    "FileVersion": 3,
    "Version": 1,
    "VersionName": "1.0",
    "FriendlyName": "ShooterCore",
    "Description": "Gameplay systems for Game1 / Shooter Game",
    "Category": "Game Features",
    "ExplicitlyLoaded": true,
    "EnabledByDefault": false,
    "BuiltInInitialFeatureState": "Registered",
    "Modules": [
        {
            "Name": "ShooterCoreRuntime",
            "Type": "Runtime",
            "LoadingPhase": "Default"
        }
    ],
    "Plugins": [
        {
            "Name": "GameplayAbilities",
            "Enabled": true
        },
        {
            "Name": "ModularGameplay",
            "Enabled": true
        },
        // 其他依赖插件
    ]
}

5.2 运行时模块初始化

ShooterCoreRuntimeModule.cpp 定义了模块的初始化和关闭逻辑:

cpp 复制代码
// 定义在 ShooterCoreRuntimeModule.cpp
void FShooterCoreRuntimeModule::StartupModule()
{
    // 模块初始化逻辑
}

void FShooterCoreRuntimeModule::ShutdownModule()
{
    // 模块关闭逻辑
}

5.3 GameFeatureData 配置

ShooterCore.uasset 配置文件包含了 ShooterCore 的所有 GameFeatureAction,如:

  • 添加射击游戏的核心能力
  • 注册输入映射
  • 添加 UI 控件
  • 配置游戏玩法提示

6. Lyra 自定义的 GameFeature 策略

LyraGameFeaturePolicy 是 Lyra 项目自定义的 GameFeature 策略类,用于控制 GameFeature 的加载模式和观察者:

cpp 复制代码
// 定义在 LyraGameFeaturePolicy.h
UCLASS(MinimalAPI, Config = Game)
class ULyraGameFeaturePolicy : public UGameFeaturesProjectPolicies
{
    GENERATED_BODY()
    
public:
    // 获取单例实例
    static ULyraGameFeaturePolicy& Get();
    
    // 初始化游戏特性管理器
    virtual void InitGameFeatureManager() override;
    
    // 关闭游戏特性管理器
    virtual void ShutdownGameFeatureManager() override;
    
    // 获取游戏特性加载模式
    virtual void GetGameFeatureLoadingMode(bool& bLoadClientData, bool& bLoadServerData) const override;
};

7. 总结

GameFeature 是 Lyra Starter Game 中实现模块化功能扩展的核心机制,ShooterCore 作为一个典型的 GameFeature 插件,其加载流程遵循了 Unreal Engine 5 的 GameFeature 生命周期:

  1. 注册阶段:发现插件并加载 GameFeatureData
  2. 加载阶段:检查依赖并预加载资源
  3. 激活阶段:执行 GameFeatureAction 并集成到游戏世界
  4. 运行阶段:功能生效
  5. 停用阶段:清理资源和功能
  6. 卸载阶段:移除插件

通过这种模块化的设计,Lyra Starter Game 可以灵活地扩展和管理游戏功能,提高代码的可维护性和复用性。

关键文件路径

  1. GameFeature 核心定义:C:\UnrealEngine-5.6.1-release\Engine\Plugins\Runtime\GameFeatures\Source\GameFeatures\Public\GameFeatureData.h
  2. Lyra GameFeature 策略:c:\Users\ChenChao\Documents\GitCode\LyraStarterGame_5.6\Source\LyraGame\GameFeatures\LyraGameFeaturePolicy.h
  3. ShooterCore 插件描述:c:\Users\ChenChao\Documents\GitCode\LyraStarterGame_5.6\Plugins\GameFeatures\ShooterCore\ShooterCore.uplugin
  4. GameFeatureAction 实现:c:\Users\ChenChao\Documents\GitCode\LyraStarterGame_5.6\Source\LyraGame\GameFeatures\

通过理解 GameFeature 的加载流程,开发者可以更好地利用这一机制来扩展和定制 Lyra Starter Game 的功能。

相关推荐
加成BUFF2 小时前
C++入门讲解3:数组与指针全面详解
开发语言·c++·算法·指针·数组
会思考的猴子2 小时前
UE5 监听设备输入
ue5
代码游侠2 小时前
应用——管道与文件描述符
linux·服务器·c语言·学习·算法
老王熬夜敲代码2 小时前
linux系统IO
linux·笔记
stars-he2 小时前
FPGA学习笔记(6)逻辑设计小结与以太网发送前置
笔记·学习·fpga开发
天若有情6733 小时前
我发明的PROTO_V4协议:一个让数据“穿上迷彩服”的发明(整数传输协议)
网络·c++·后端·安全·密码学·密码·数据
加油=^_^=3 小时前
【C++11】特殊类设计 | 类型转换
c++·单例模式·类型转换
锦瑟弦音3 小时前
跑酷游戏开发笔记3 && 游戏开始场景 cocos 3.8.7
javascript·笔记·游戏
加成BUFF3 小时前
C++入门详解2:数据类型、运算符与表达式
c语言·c++·计算机