LyraStarterGame_5.6 Experience系统分析

1. 核心概念

Experience(经验)是Lyra游戏的核心配置单元,用于定义:

  • 要激活的游戏特性插件
  • 默认Pawn数据
  • 经验加载/激活时执行的动作
  • 可复用的动作集合

2. 主要组件

2.1 ULyraExperienceDefinition

定义在LyraExperienceDefinition.h中,是一个PrimaryDataAsset,包含:

复制代码
cpp 复制代码
UPROPERTY(EditDefaultsOnly, Category = Gameplay)

TArray<FString> GameFeaturesToEnable; // 要启用的游戏特性列表

UPROPERTY(EditDefaultsOnly, Category=Gameplay)

TObjectPtr<const ULyraPawnData> DefaultPawnData; // 默认Pawn数据

UPROPERTY(EditDefaultsOnly, Instanced, 

Category="Actions")

TArray<TObjectPtr<UGameFeatureAction>> Actions; // 游戏特性操作列表

UPROPERTY(EditDefaultsOnly, Category=Gameplay)

TArray<TObjectPtr<ULyraExperienceActionSet>> 

ActionSets; // 经验操作集列表

2.2 ULyraExperienceActionSet

定义在LyraExperienceActionSet.h中,用于组合可复用的动作:

复制代码
cpp 复制代码
UPROPERTY(EditAnywhere, Instanced, Category="Actions to Perform")

TArray<TObjectPtr<UGameFeatureAction>> Actions; // 游戏特性操作列表

UPROPERTY(EditAnywhere, Category="Feature Dependencies")

TArray<FString> GameFeaturesToEnable; // 要启用的游戏特性列表

2.3 ULyraExperienceManagerComponent

定义在LyraExperienceManagerComponent.h/cpp中,是Experience系统的核心管理器,负责:

  • 经验的加载和激活
  • 状态管理和转换
  • 游戏特性插件的加载和激活
  • 动作的执行
  • 网络复制

3. 经验加载流程

Experience系统的加载流程包含以下关键步骤:

3.1 设置当前经验

复制代码
cpp 复制代码
void ULyraExperienceManagerComponent::SetCurrentExperience(FPrimaryAssetId ExperienceId)

{

    // 通过资源ID获取经验定义

    // 设置当前经验并开始加载

    StartExperienceLoad();

}

3.2 开始加载过程

复制代码
cpp 复制代码
void ULyraExperienceManagerComponent::StartExperienceLoad()

{

    // 加载经验定义和相关资源

    // 异步加载资源包

    // 绑定资源加载完成回调

}

3.3 资源加载完成

复制代码
cpp 复制代码
void ULyraExperienceManagerComponent::OnExperienceLoadComplete()

{

    // 收集游戏特性插件URL

    // 加载并激活游戏特性插件

    // 状态转换为LoadingGameFeatures

}

3.4 游戏特性插件加载完成

复制代码
cpp 复制代码
void ULyraExperienceManagerComponent::OnGameFeaturePluginLoadComplete(const UE::GameFeaturs::FResult& Result)

{

    // 减少正在加载的插件计数

    // 当所有插件加载完成后,调用

    OnExperienceFullLoadCompleted()

}

3.5 经验完全加载完成

复制代码
cpp 复制代码
void ULyraExperienceManagerComponent::OnExperienceFullLoadCompleted()

{

    // 执行经验和动作集中的所有动作

    // 状态转换为ExecutingActions → Loaded

    // 广播加载完成事件(高、中、低优先级)

}

4. 状态转换

Experience系统有以下状态转换:

  • Unloaded → Loading → LoadingGameFeatures → ExecutingActions → Loaded
  • 支持Deactivating状态用于停用经验
  • 支持LoadingChaosTestingDelay状态用于测试延迟

5. 关键功能特性

5.1 网络复制

  • 当前经验会自动复制到客户端
  • 客户端在收到复制的经验后会自动开始加载

5.2 优先级事件系统

支持三种优先级的加载完成事件:

  • CallOrRegister_OnExperienceLoaded_HighPriority:高优先级,用于游戏核心功能
  • CallOrRegister_OnExperienceLoaded:普通优先级
  • CallOrRegister_OnExperienceLoaded_LowPriority:低优先级,用于非核心功能

5.3 异步加载

  • 资源和游戏特性插件采用异步加载方式
  • 支持合并多个异步加载请求
  • 支持取消加载处理

5.4 动作执行系统

  • 支持在经验加载/激活/停用/卸载时执行动作
  • 动作可以来自经验定义或动作集
  • 支持动作的组合和复用

6. 使用示例

在LyraGameMode.cpp中,Experience系统被用于获取默认Pawn数据:

复制代码
cpp 复制代码
const ULyraPawnData*  ALyraGameMode::GetPawnDataForController(const AController* InController) const

{

    // 首先从PlayerState获取Pawn数据

    // 如果没有,从当前经验中获取默认Pawn数据

    ULyraExperienceManagerComponent* ExperienceComponent = GameState->FindComponentByClass<ULyraExperienceManagerComponent>();

    check(ExperienceComponent);

    if (ExperienceComponent->IsExperienceLoaded())

    {

        const ULyraExperienceDefinition* Experience = ExperienceComponent->GetCurrentExperienceChecked();

        if (Experience->DefaultPawnData != nullptr)

        {

            return Experience->DefaultPawnData;

        }

        return ULyraAssetManager::Get().

        GetDefaultPawnData();

    }

    return nullptr;

}

7. 设计特点

  • 模块化设计:将游戏功能拆分为可复用的游戏特性插件
  • 数据驱动:使用PrimaryDataAsset定义经验,便于配置和管理
  • 异步加载:提高游戏性能和响应性
  • 网络同步:确保客户端和服务器使用相同的游戏配置
  • 可扩展性:支持通过动作集扩展经验功能

8. 学习建议

要深入学习Experience系统,建议:

  1. 理解PrimaryDataAsset的概念和使用方法
  2. 学习GameFeature插件的开发和管理
  3. 研究异步加载和资源管理
  4. 分析经验加载流程的状态转换
  5. 理解动作执行系统的设计和实现

通过掌握这些概念,您可以更好地理解Lyra游戏的架构设计,并应用到自己的项目中。

相关推荐
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
RainCity2 天前
Java Swing 自定义组件库分享(十二)
java·笔记·后端
BadBadBad__AK2 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境3 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境3 天前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
郝学胜_神的一滴4 天前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
卷无止境6 天前
C++ 的Eigen 库全解析
c++
卷无止境6 天前
现代 C++特性大盘点:一门脱胎换骨的老语言
c++·后端
郝学胜_神的一滴6 天前
CMake 27:缓存变量的特性、语法、类型与实操全解
c++·cmake
博客18008 天前
酷宝的使用方法,超好用的免费界面库,C++、MFC可用
c++·mfc·界面库·库来帮·酷宝