Files
BlueRoseNote/RPGGameplayAbility重构文档.md

30 KiB
Raw Blame History

tags, date, project, plugin, status
tags date project plugin status
GAS
UE5
架构
重构
插件
2026-05-30 MusicFighterGame RPGGameplayAbility 设计阶段

RPGGameplayAbility 插件重构文档

概述

本文档基于对以下三个 UE5 项目的深度研究,分析其 GameplayAbilitySystem (GAS) 架构、插件设计和技术亮点,并对 RPGGameplayAbility 插件提出全面的重构建议。

研究项目

项目 类型 亮点
LyraStarterGame Epic 官方 UE5 示例 GameFeature 模块化、GameplayTag 输入路由、装备系统、GamePhase
GASShooter Epic 官方 UE4 射击示例 多 Mesh 蒙太奇、武器能力授予、EffectContainer、可重用 TargetActor
UE5_GAS_Aura 社区 RPG 教程项目 三层属性模型、MMC 派生属性、MVVC WidgetController、DataAsset 驱动

当前插件现状

RPGGameplayAbility 插件基于 GASShooter 框架衍生,已具备:

  • 多 Mesh 蒙太奇复制系统
  • EffectContainer + TargetType 效果容器系统
  • RPC 批处理 (ShouldDoServerAbilityRPCBatch)
  • 伤害元属性模式 (DamageExecutionCalc)
  • 可重用 GATA_Trace 瞄准 Actor
  • GameplayMessageSubsystem 基础设施

但存在以下核心架构问题:

  • 硬编码 EGSAbilityInputID 枚举输入绑定
  • 单一巨型属性集 (18 个属性)
  • 角色基类手动维护 15+ 个属性 getter 函数
  • 无 AbilitySet DataAsset 模块化能力配置
  • LoadingScreen 模块耦合在 gameplay 插件中
  • 无 GameplayTag 驱动的输入路由
  • 无 MVVM/WidgetController UI 模式
  • 无装备/武器系统与 GAS 集成
  • 无队伍/阵营系统
  • 无 GamePhase 阶段管理
  • 硬编码骨骼名称 ("b_head")

核心重构优先级

优先级 1GameplayTag 输入路由替换硬编码枚举

[!important] 最高优先级 这是影响最大的单一改动Lyra 和 Aura 都采用此模式。

当前实现(差):

// RPGAbilityTypes.h
UENUM(BlueprintType)
enum class EGSAbilityInputID : uint8 {
    None = 0, Confirm = 1, Cancel = 2,
    Sprint = 3, Jump = 4, PrimaryFire = 5,
    SecondaryFire = 6, AlternateFire = 7,
    Reload = 8, NextWeapon = 9, PrevWeapon = 10,
    Interact = 11
};

推荐实现Lyra 模式):

// RPGInputConfig.h - DataAsset 驱动
USTRUCT(BlueprintType)
struct FRPGInputAction {
    UPROPERTY(EditDefaultsOnly)
    TObjectPtr<const UInputAction> InputAction;
    
    UPROPERTY(EditDefaultsOnly)
    FGameplayTag InputTag;
};

UCLASS(BlueprintType)
class URPGInputConfig : public UDataAsset {
    UPROPERTY(EditDefaultsOnly)
    TArray<FRPGInputAction> AbilityInputActions;
    
    UPROPERTY(EditDefaultsOnly)
    TArray<FRPGInputAction> NativeInputActions;
};

// RPGInputComponent.h - 模板绑定
class URPGInputComponent : public UEnhancedInputComponent {
    template<class UserClass, typename PressedFuncType, 
             typename ReleasedFuncType, typename HeldFuncType>
    void BindAbilityActions(const URPGInputConfig* InputConfig, 
        UserClass* Object, PressedFuncType PressedFunc,
        ReleasedFuncType ReleasedFunc, HeldFuncType HeldFunc);
};

// RpgAbilitySystemComponent.h - ASC 输入处理
void URPGAbilitySystemComponent::AbilityInputTagPressed(FGameplayTag InputTag) {
    for (FGameplayAbilitySpec& Spec : ActivatableAbilities.Items) {
        if (Spec.GetDynamicSpecSourceTags().HasTagExact(InputTag)) {
            Spec.InputPressed = true;
            if (Spec.IsActive()) {
                AbilitySpecInputPressed(Spec);
            } else {
                TryActivateAbility(Spec.Handle);
            }
        }
    }
}

优势:

  • 新增能力无需重新编译枚举
  • 输入可通过 DataAsset 按角色重新绑定
  • GameFeature 插件可在不接触核心代码的情况下添加新输入标签
  • 支持 Pressed/Held/Released 三种策略(类似 Aura 的 AbilityInputTagHeld/Released

优先级 2拆分巨型属性集

[!important] 核心架构改动 Aura 的三层属性模型是 RPG 游戏的标准做法。

当前问题: RPGAttributeSetBase 包含 18 个属性,混在一起不可拆分。

推荐结构:

// 第一层:主要属性(可投入加点的属性)
UCLASS()
class URPGVitalAttributeSet : public UAttributeSet {
    // Health, MaxHealth, HealthRegenRate
    // Mana, MaxMana, ManaRegenRate
    // Stamina, MaxStamina, StaminaRegenRate
    // Shield, MaxShield, ShieldRegenRate
};

// 第二层:次要属性(通过 MMC 派生的战斗属性)
UCLASS()
class URPGCombatAttributeSet : public UAttributeSet {
    // Armor, ArmorPenetration
    // CritChance, CritDamage, CritResistance
    // BlockChance
    // MoveSpeed
};

// 第三层:主要属性(核心加点属性)
UCLASS()
class URPGPrimaryAttributeSet : public UAttributeSet {
    // Strength, Intelligence, Agility, Vitality
};

// Meta 属性(临时、非复制、仅服务器)
UCLASS()
class URPGMetaAttributeSet : public UAttributeSet {
    // Damage (meta, 仅服务器)
    // Healing (meta, 仅服务器)
};

// 进度属性
UCLASS()
class URPGProgressionAttributeSet : public UAttributeSet {
    // CharacterLevel, XP, Gold
};

MMC 派生属性计算Aura 模式):

// MMC_MaxHealth.cpp
float UMMC_MaxHealth::CalculateBaseMagnitude_Implementation(
    const FGameplayEffectSpec& Spec) const {
    
    float Vitality = 0.f;
    GetCapturedAttributeMagnitude(
        VitalityDef, Spec, FAggregatorEvaluateParameters(), Vitality);
    
    int32 Level = 1;
    if (Spec.GetContext().GetSourceObject()) {
        // 通过 ICombatInterface 获取等级
    }
    
    return 80.f + 2.5f * Vitality + 10.f * Level;
}

优先级 3引入 AbilitySet DataAsset

[!important] 模块化配置 替换硬编码的 CharacterAbilities 数组。

USTRUCT(BlueprintType)
struct FRPGGameplayAbilitySet_GameplayAbility {
    UPROPERTY(EditDefaultsOnly)
    TSubclassOf<URPGGameplayAbility> Ability;
    
    UPROPERTY(EditDefaultsOnly)
    int32 AbilityLevel = 1;
    
    UPROPERTY(EditDefaultsOnly)
    FGameplayTag InputTag;
    
    UPROPERTY(EditDefaultsOnly)
    ERPGAbilityActivationPolicy ActivationPolicy;
};

USTRUCT(BlueprintType)
struct FRPGGameplayAbilitySet_GameplayEffect {
    UPROPERTY(EditDefaultsOnly)
    TSubclassOf<UGameplayEffect> GameplayEffect;
    
    UPROPERTY(EditDefaultsOnly)
    float EffectLevel = 1.f;
};

USTRUCT(BlueprintType)
struct FRPGGameplayAbilitySet_AttributeSet {
    UPROPERTY(EditDefaultsOnly)
    TSubclassOf<UAttributeSet> AttributeSet;
};

UCLASS(BlueprintType)
class URPGGameplayAbilitySet : public UPrimaryDataAsset {
    GENERATED_BODY()
public:
    UPROPERTY(EditDefaultsOnly)
    TArray<FRPGGameplayAbilitySet_GameplayAbility> GrantedAbilities;
    
    UPROPERTY(EditDefaultsOnly)
    TArray<FRPGGameplayAbilitySet_GameplayEffect> GrantedEffects;
    
    UPROPERTY(EditDefaultsOnly)
    TArray<FRPGGameplayAbilitySet_AttributeSet> GrantedAttributes;
    
    void GiveToAbilitySystem(
        URPGAbilitySystemComponent* ASC,
        FRPGGameplayAbilitySet_GrantedHandles& OutHandles,
        UObject* SourceObject = nullptr) const;
    
    void TakeFromAbilitySystem(
        FRPGGameplayAbilitySet_GrantedHandles& Handles) const;
};

使用场景:

  • 角色职业定义:DA_FighterAbilitySetDA_MageAbilitySet
  • 武器/装备授予:装备授予 DA_SwordAbilitySet
  • 被动技能树:技能树节点授予特定的 AbilitySet
  • Buff/Debuff临时添加/移除 AbilitySet

优先级 4MVVM WidgetController UI 模式

[!important] UI 解耦 当前插件直接在角色代码中 push UI 数据,耦合度高。

Aura 的 WidgetController 架构:

┌─────────────────────────────────────────────────┐
│  FWidgetControllerParams模型数据              │
│  - PlayerController                              │
│  - PlayerState                                   │
│  - AbilitySystemComponent                        │
│  - AttributeSet                                  │
└──────────────┬──────────────────────────────────┘
               │
┌──────────────▼──────────────────────────────────┐
│  URPGWidgetControllerViewModel 基类)           │
│  - BroadcastInitialValues()                      │
│  - BindCallbacksToDependencies()                 │
│  - 所有权PlayerController                      │
└──────────────┬──────────────────────────────────┘
               │
    ┌──────────┴──────────┐
    │                     │
┌───▼──────────┐  ┌──────▼──────────┐
│ OverlayWidget │  │ AttributeMenu   │
│ Controller    │  │ WidgetController│
│ - Health/Mana │  │ - 动态属性菜单  │
│ - Messages    │  │ - TagsToAttrs   │
└───┬───────────┘  └──────┬──────────┘
    │                     │
┌───▼─────────────────────▼──────────────────────┐
│  URPGUserWidgetView - UMG Blueprint          │
│  - SetWidgetController() 事件                    │
│  - 绑定 BlueprintAssignable 委托                │
└─────────────────────────────────────────────────┘

HUD 工厂模式:

UCLASS()
class ARPGHUD : public AHUD {
    // 懒加载单例工厂
    UOverlayWidgetController* GetOverlayWidgetController(
        const FRPGWidgetControllerParams& Params);
    
    UAttributeMenuWidgetController* GetAttributeMenuWidgetController(
        const FRPGWidgetControllerParams& Params);
};

优先级 5插件模块拆分

当前问题: 5 个模块RPGGameplayAbility、CommonLoadingScreen、CommonStartupLoadingScreen、GameplayMessageRuntime、GameplayMessageNodes全部在一个插件中。

推荐结构:

Plugins/
├── RPGGameplayAbility/          # 核心 GAS 扩展
│   ├── Source/
│   │   └── RPGGameplayAbility/  # 唯一模块
│   └── RPGGameplayAbility.uplugin
│
├── CommonLoadingScreen/         # 独立加载画面插件
│   └── CommonLoadingScreen.uplugin
│
├── CommonStartupLoadingScreen/  # 独立启动加载画面插件
│   └── CommonStartupLoadingScreen.uplugin
│
└── GameplayMessageRouter/       # 消息路由器(保持独立)
    ├── GameplayMessageRuntime/
    └── GameplayMessageNodes/

各系统详细重构建议

1. ASC 扩展 (URPGAbilitySystemComponent)

保留:

  • 多 Mesh 蒙太奇复制系统(格斗游戏需要 1P/3P 双骨骼)
  • RPC 批处理 (ShouldDoServerAbilityRPCBatch)
  • Blueprint 标签操作辅助函数
  • 本地 GameplayCue 执行

新增(来自 Lyra

功能 说明
AbilityInputTagPressed/Released/Held GameplayTag 驱动的输入处理
ProcessAbilityInput(DeltaTime) 每帧统一的输入分发
激活组系统 Independent / Exclusive_Replaceable / Exclusive_Blocking
动态 Tag GE 应用 运行时 Tag 管理
TagRelationshipMapping 支持 跨能力阻塞/取消关系

新增(来自 Aura

功能 说明
ClientEffectApplied RPC GE 应用时客户端通知 UI
m_EffectAssetTag 多播委托 Widget 创建触发

激活组系统(格斗游戏关键):

UENUM(BlueprintType)
enum class ERPGAbilityActivationGroup : uint8 {
    Independent,            // 不阻塞任何能力,不被任何能力阻塞
    Exclusive_Replaceable,  // 可被其他 Exclusive 能力取消
    Exclusive_Blocking,     // 阻塞其他 Exclusive 能力,自身不可被取消
};

// 使用场景:
// - 普通攻击Independent可叠加
// - 必杀技Exclusive_Replaceable会被新必杀技取消
// - 超必杀技Exclusive_Blocking不可取消阻塞其他技能
// - 防御/受击Exclusive_Blocking不可取消

2. GameplayAbility 基类 (URPGGameplayAbility)

保留:

  • EffectContainer 系统Tag → TargetType + GEs
  • 自定义 Cost 检查RPGCheckCost/RPGApplyCost BlueprintNativeEvent
  • 多 Mesh 动画辅助函数

新增(来自 Lyra

UENUM(BlueprintType)
enum class ERPGAbilityActivationPolicy : uint8 {
    OnInputTriggered,   // 按键按下触发
    WhileInputActive,   // 按键持续期间激活
    OnSpawn,            // 授予时立即激活(被动能力)
    OnRhythmBeat,       // 节奏节拍触发MusicFighter 特有)
};

// 组合式 Cost 系统
UCLASS(Abstract, EditInlineNew, DefaultToInstanced)
class URPGAbilityCost : public UObject {
    virtual bool CheckCost(const URPGGameplayAbility* Ability,
        const FGameplayAbilitySpecHandle Handle,
        const FGameplayAbilityActorInfo* ActorInfo,
        FGameplayTagContainer* OptionalRelevantTags) const;
    
    virtual void ApplyCost(const URPGGameplayAbility* Ability,
        const FGameplayAbilitySpecHandle Handle,
        const FGameplayAbilityActorInfo* ActorInfo,
        const FGameplayAbilityActivationInfo ActivationInfo);
};

// 子类:
// - URPGAbilityCost_GameplayEffectGE 消耗)
// - URPGAbilityCost_ItemTagStack物品标记栈消耗如弹药
// - URPGAbilityCost_Attribute直接属性消耗如怒气值

删除/替换:

  • EGSAbilityInputID AbilityInputIDFGameplayTag StartupInputTag
  • bActivateOnInputERPGAbilityActivationPolicy ActivationPolicy
  • bSourceObjectMustEqualCurrentWeaponToActivate → 泛化为 Tag 需求检查

3. 属性系统 - 完整重构

Primary Attributes主要/可投资属性)
├── Strength       → 影响 PhysicalAttack, MaxHealth
├── Intelligence   → 影响 MagicAttack, MaxMana
├── Agility        → 影响 CritChance, MoveSpeed, DodgeChance
└── Vitality       → 影响 MaxHealth, MaxStamina, HealthRegenRate

Secondary Attributes派生/战斗属性 - 通过 MMC 计算)
├── MaxHealth      = f(Vitality, Level)
├── MaxMana        = f(Intelligence, Level)
├── MaxStamina     = f(Vitality, Level)
├── PhysicalAttack = f(Strength, Level)
├── MagicAttack    = f(Intelligence, Level)
├── Armor          = f(Agility, Vitality, Level)
├── ArmorPenetration = f(Strength, Level)
├── CritChance     = f(Agility, Level)
├── CritDamage     = 1.5x (基础) + 装备加成
├── CritResistance = f(Vitality, Level)
├── BlockChance    = f(Strength, Level)
├── DodgeChance    = f(Agility, Level)
└── MoveSpeed      = Base(400) + f(Agility, Level)

Vital Attributes运行时资源
├── Health         → [0, MaxHealth]
├── Mana           → [0, MaxMana]
└── Stamina        → [0, MaxStamina]

Meta Attributes临时服务器专用
├── Damage         → ExecutionCalc 写入 → PostGameplayEffectExecute 处理后归零
└── Healing        → HealingExecutionCalc 写入 → 处理后归零

Progression进度
├── CharacterLevel → 影响所有 MMC 计算
├── XP             → 经验值
└── Gold           → 货币

伤害计算管道:

1. 技能设置 SetByCaller Magnitude (Tag: "Data.Damage")
2. URPGDamageExecutionCalc 捕获:
   - Source: PhysicalAttack/MagicAttack
   - Target: Armor, ArmorPenetration, CritResistance, BlockChance, DodgeChance
3. 计算流程:
   a. 命中判定 (DodgeChance)
   b. 暴击判定 (CritChance vs CritResistance)
   c. 格挡判定 (BlockChance)
   d. 护甲减免 (Armor vs ArmorPenetration)
   e. 属性克制修正(元素标签)
   f. 最终伤害写入 Target.Damage
4. PostGameplayEffectExecute:
   a. Shield 吸收
   b. Health 扣减 → Clamp
   c. 存活/死亡判定 → 广播 (GameplayMessageSubsystem)

4. 瞄准系统

保留:

  • URPGTargetType 蓝图化瞄准逻辑
  • RPGATA_Trace / RPGATA_LineTrace / RPGATA_SphereTrace

新增(格斗游戏专用):

// 近战弧形瞄准
UCLASS(Blueprintable)
class URPGTargetType_MeleeArc : public URPGTargetType {
    UPROPERTY(EditDefaultsOnly)
    float ArcAngle = 90.f;  // 弧形角度
    
    UPROPERTY(EditDefaultsOnly)
    float ArcRadius = 200.f;  // 弧形半径
};

// AOE 圆形瞄准
UCLASS(Blueprintable)
class URPGTargetType_CircleAOE : public URPGTargetType {
    UPROPERTY(EditDefaultsOnly)
    float Radius = 300.f;
};

// 组合状态过滤
// "已在此连招中被击中过的目标不重复选取"
void GetTargets_Implementation(...) {
    // 检查 Combat.AlreadyHit 标签
    for (AActor* Target : Candidates) {
        if (!Target->HasMatchingGameplayTag(Combat_AlreadyHit)) {
            OutActors.Add(Target);
        }
    }
}

5. 输入系统

替换整个 EGSAbilityInputID 枚举为以下架构:

┌─────────────────────────┐
│  URPGInputConfig        │  DataAsset
│  - AbilityInputActions  │  映射 InputAction → GameplayTag
│  - NativeInputActions   │
└───────────┬─────────────┘
            │
┌───────────▼─────────────┐
│  URPGInputComponent     │  extends UEnhancedInputComponent
│  - BindAbilityActions() │  模板函数,自动绑定
└───────────┬─────────────┘
            │
┌───────────▼─────────────┐
│  ULyraHeroComponent     │  (或 RPGHeroComponent)
│  - InitializePlayerInput│
└───────────┬─────────────┘
            │
┌───────────▼─────────────┐
│  URPGAbilitySystemComp  │
│  - AbilityInputTagPressed│  匹配 DynamicSpecSourceTags
│  - AbilityInputTagReleased│
│  - AbilityInputTagHeld  │
│  - ProcessAbilityInput  │  每帧统一处理
└─────────────────────────┘

MusicFighter 特有:节奏输入缓冲

// 在 ProcessAbilityInput 中
void URPGAbilitySystemComponent::ProcessAbilityInput(float DeltaTime, bool bGamePaused) {
    // ... 标准处理 ...
    
    // 节奏检测
    if (bIsOnBeat) {
        for (FGameplayAbilitySpec& Spec : ActivatableAbilities.Items) {
            if (Spec.Ability->GetActivationPolicy() == OnRhythmBeat) {
                // 应用节奏加成标签
                Spec.DynamicSpecSourceTags.AddTag(RhythmBonusTag);
            }
        }
    }
    
    // 输入缓冲(格斗游戏标准做法)
    FlushInputBuffer(DeltaTime);
}

6. UI 系统

当前问题: 直接在 Character/PlayerState/PlayerController 中 push UI 数据。

使用 Aura 的 MVVC 模式替换:

// WidgetController 管理 ASC 委托绑定
// Widget (UMG) 仅负责显示
// 中间通过 BlueprintAssignable 委托通信

// 消息 Widget 通过 DataTable 驱动:
USTRUCT(BlueprintType)
struct FRPGMessageWidgetRow : public FTableRowBase {
    UPROPERTY(EditAnywhere)
    FGameplayTag MessageTag;
    
    UPROPERTY(EditAnywhere)
    TSubclassOf<URPGUserWidget> MessageWidgetClass;
    
    UPROPERTY(EditAnywhere)
    UTexture2D* MessageImage;
    
    UPROPERTY(EditAnywhere)
    FText MessageText;
};

GameplayMessageSubsystem 集成:

// 替换直接调用 PC->ShowDamageNumber(...)
// 使用消息通道广播:
UGameplayMessageSubsystem::Get(this).BroadcastMessage(
    RPGGameplayTags::Get().DamageDealt,
    FRPGDamageMessage{
        Instigator, Target, Damage, DamageTags
    }
);

// UI Widget 订阅:
UGameplayMessageSubsystem::Get(this).RegisterListener<FRPGDamageMessage>(
    RPGGameplayTags::Get().DamageDealt,
    this, &URPGDamageWidget::OnDamageMessage
);

7. 装备系统

[!note] 新增功能 当前插件无装备系统,使用 Lyra 模式新增。

// 装备定义DataAsset
UCLASS(BlueprintType)
class URPGEquipmentDefinition : public UObject {
    UPROPERTY(EditDefaultsOnly)
    TSubclassOf<URPGEquipmentInstance> InstanceType;
    
    UPROPERTY(EditDefaultsOnly)
    TArray<URPGGameplayAbilitySet*> AbilitySetsToGrant;
    
    UPROPERTY(EditDefaultsOnly)
    TArray<FRPGEquipmentActorToSpawn> ActorsToSpawn;
};

// 装备实例(运行时)
UCLASS(BlueprintType)
class URPGEquipmentInstance : public UObject {
    // 授予的能力句柄
    FRPGGameplayAbilitySet_GrantedHandles GrantedHandles;
    
    // 关联的源对象(武器/乐器/道具)
    UObject* GetInstigator() const;
};

// 装备管理器组件(挂在 Pawn 上)
UCLASS()
class URPGEquipmentManagerComponent : public UPawnComponent {
    UFUNCTION(BlueprintCallable)
    void EquipItem(TSubclassOf<URPGEquipmentDefinition> EquipmentDef);
    
    UFUNCTION(BlueprintCallable)
    void UnequipItem(URPGEquipmentInstance* EquipmentInstance);
};

// 装备能力基类
UCLASS()
class URPGGameplayAbility_FromEquipment : public URPGGameplayAbility {
    // 可反查装备实例获取属性/状态
    URPGEquipmentInstance* GetAssociatedEquipment() const;
};

8. GamePhase 阶段系统

[!note] 新增功能 音乐格斗游戏需要回合管理。

UCLASS()
class URPGamePhaseSubsystem : public UWorldSubsystem {
    // 使用层级 GameplayTag 管理阶段
    // Game.WaitingForPlayers
    // Game.Countdown
    // Game.Playing.Round1
    // Game.Playing.Round1.Break
    // Game.Playing.Round2
    // Game.ShowingResult
    
    void StartPhase(TSubclassOf<URPGamePhaseAbility> PhaseAbility,
        FRPGamePhaseDelegate PhaseEndedCallback);
    
    void WhenPhaseStartsOrIsActive(FGameplayTag PhaseTag,
        EPhaseTagMatchType MatchType,
        const FRPGamePhaseTagDelegate& WhenActive);
    
    void WhenPhaseEnds(FGameplayTag PhaseTag,
        EPhaseTagMatchType MatchType,
        const FRPGamePhaseTagDelegate& WhenEnd);
};

// 阶段能力
UCLASS()
class URPGamePhaseAbility : public URPGGameplayAbility {
    // ReplicationPolicy = ReplicateNo
    // NetExecutionPolicy = ServerInitiated
    // NetSecurityPolicy = ServerOnly
    
    UPROPERTY(EditDefaultsOnly)
    FGameplayTag GamePhaseTag;
};

能力阶段门控:

  • ActivationRequiredTags 添加 Game.Playing → 非 Playing 阶段无法使用能力
  • ActivationBlockedTags 添加 Game.ShowingResult → 结果显示时禁用能力
  • 阶段观察者音乐播放、UI 切换、生成逻辑

9. 队伍系统

[!note] 新增功能 格斗游戏需要队伍/阵营支持。

UCLASS()
class URPGTeamSubsystem : public UWorldSubsystem {
    void ChangeTeamForActor(AActor* Actor, int32 NewTeamId);
    int32 FindTeamFromObject(UObject* Obj) const;
    bool CanCauseDamage(AActor* Instigator, AActor* Target) const;
    
    // 队伍标记栈(跟踪队伍得分等)
    void AddTeamTagStack(int32 TeamId, FGameplayTag Tag, int32 Count);
    void RemoveTeamTagStack(int32 TeamId, FGameplayTag Tag, int32 Count);
    int32 GetTeamTagStackCount(int32 TeamId, FGameplayTag Tag) const;
};

// ILyraTeamAgentInterface 实现
class ILyraTeamAgentInterface : public IGenericTeamAgentInterface {
    FOnLyraTeamIndexChangedDelegate OnTeamChanged;
};

实施路线图

阶段 1基础改造低风险、高回报

# 改动 <EFBFBD><EFBFBD><EFBFBD> 影响范围
1 拆分属性集为 Primary/Combat/Vital/Meta/Progression Aura 属性系统
2 GameplayTag 输入路由替换 EGSAbilityInputID 枚举 Lyra 输入/ASC
3 创建 RPGInputConfig DataAsset + RPGInputComponent Lyra+Aura 输入
4 实现 AbilitySet DataAsset 模块化能力授予 Lyra 能力授予

阶段 2核心改进

# 改动 来源 影响范围
5 能力激活策略 (OnInputTriggered/WhileInputActive/OnSpawn/OnRhythmBeat) Lyra 能力基类
6 MMC 派生属性计算(含等级缩放) Aura 属性系统
7 激活组系统(格斗游戏攻击取消) Lyra ASC
8 重构伤害管道Meta属性 + ExecutionCalc Lyra+GASShooter 伤害
9 ClientEffectApplied RPC UI 通知 Aura ASC/UI

阶段 3架构升级

# 改动 来源 影响范围
10 MVVM WidgetController UI 模式 Aura UI
11 拆分 LoadingScreen 为独立插件 最佳实践 插件结构
12 GameplayMessageSubsystem 集成(解耦事件) Lyra 全局通信
13 装备系统(装备 → AbilitySet → ASC Lyra 装备/物品
14 GamePhase 阶段系统(回合管理) Lyra 游戏流程

阶段 4高级特性

# 改动 来源 影响范围
15 TagRelationshipMapping 跨能力阻塞/取消 Lyra 能力管理
16 组合式能力 Cost 系统 Lyra 能力消耗
17 队伍子系统 Lyra 队伍/阵营
18 GameFeature 模块化扩展 Lyra 插件架构
19 Save/Load GAS 状态序列化 自定义 存档

MusicFighterGame 特有建议

节奏输入系统

// 在 ASC 中添加
void URPGAbilitySystemComponent::SetCurrentBeatFraction(float BeatFraction) {
    // 从 FMOD/AudioAnalysis 获取节拍数据
    CurrentBeatPrecision = CalculateBeatPrecision(BeatFraction);
    
    if (CurrentBeatPrecision < PerfectThreshold) {
        // Perfect 判定
        AddDynamicTagToAllAbilities(RhythmPerfectTag);
    } else if (CurrentBeatPrecision < GoodThreshold) {
        // Good 判定
        AddDynamicTagToAllAbilities(RhythmGoodTag);
    }
}

连招系统建议

利用 GameplayTag 层级管理连招状态:
- Combat.Combo.Hit1 → Combat.Combo.Hit2 → Combat.Combo.Hit3
- 每个连招段使用 EffectContainer Map 的不同 Tag
- 下一段能力需要上一段的 Tag 作为 ActivationRequiredTag
- 节奏加成通过 SetByCaller 修改伤害系数

乐器/武器即 AbilitySource

游戏中的乐器(吉他、贝斯、鼓、键盘)作为 Equipment
- 每个乐器有独立的 AbilitySet
- 不同乐器授予不同的攻击模式和效果
- 节奏精准度影响伤害倍率
- 装备管理器处理乐器切换

对比总结

系统 当前状态 目标状态 参考来源
输入路由 硬编码枚举 GameplayTag 驱动 Lyra
属性系统 单一 18 属性集 5 个分层属性集 + MMC Aura
能力配置 CharacterAbilities 数组 AbilitySet DataAsset Lyra
UI 模式 直接 Push MVVM WidgetController Aura
伤害计算 ExecutionCalc + AttributeSet 混用 完整 Meta 属性管道 Lyra+GASShooter
插件模块 5 模块混装 核心 + 独立 LoadingScreen 最佳实践
装备系统 装备 → AbilitySet → ASC Lyra
阶段管理 层级 Tag GamePhase 子系统 Lyra
队伍系统 TeamSubsystem + TeamAgent Lyra
消息通信 已引入未使用 GameplayMessageSubsystem 全系统集成 Lyra
多 Mesh 蒙太奇 已实现 保留并优化 GASShooter
EffectContainer 已实现 保留并扩展类型 GASShooter
RPC 批处理 已实现 保留 GASShooter

附录

参考项目文件索引

LyraStarterGame:

  • Source/LyraGame/AbilitySystem/LyraAbilitySystemComponent.h - ASC 标签输入 + 激活组
  • Source/LyraGame/AbilitySystem/Abilities/LyraGameplayAbility.h - 能力基类 + 策略
  • Source/LyraGame/AbilitySystem/LyraAbilitySet.h - AbilitySet DataAsset
  • Source/LyraGame/AbilitySystem/Phases/LyraGamePhaseSubsystem.h - 阶段子系统
  • Source/LyraGame/AbilitySystem/Attributes/LyraHealthSet.h - 元属性模式
  • Source/LyraGame/Equipment/LyraEquipmentDefinition.h - 装备定义
  • Source/LyraGame/Input/LyraInputConfig.h - 输入 DataAsset
  • Source/LyraGame/GameFeatures/GameFeatureAction_AddAbilities.h - 模块化能力授予
  • Plugins/GameplayMessageRouter/Source/.../GameplayMessageSubsystem.h - 消息系统

GASShooter:

  • Source/GASShooter/Characters/Abilities/GSAbilitySystemComponent.h - 多 Mesh ASC
  • Source/GASShooter/Characters/Abilities/GSGameplayAbility.h - 能力基类
  • Source/GASShooter/Characters/Abilities/AttributeSets/GSAttributeSetBase.h - 属性集
  • Source/GASShooter/Characters/Abilities/GSDamageExecutionCalc.cpp - 伤害计算
  • Source/GASShooter/Characters/Abilities/GSAbilityTypes.h - EffectContainer
  • Source/GASShooter/Weapons/GSWeapon.h - 武器系统
  • Source/GASShooter/Characters/Abilities/GSGATA_Trace.h - 瞄准系统

UE5_GAS_Aura:

  • Source/Aura/Public/AbilitySystem/AuraAbilitySystemComponent.h - Tag 输入 ASC
  • Source/Aura/Public/AbilitySystem/AuraAttributeSet.h - 三层属性集 + TagsToAttributes
  • Source/Aura/Public/AbilitySystem/Abilities/AuraGameplayAbility.h - 能力基类
  • Source/Aura/Public/AbilitySystem/ModMagCalc/MMC_MaxHealth.cpp - MMC 示例
  • Source/Aura/Public/Input/AuraInputConfig.h - 输入 DataAsset
  • Source/Aura/Public/Input/AuraInputComponent.h - 输入组件模板
  • Source/Aura/Public/UI/WidgetController/AuraWidgetController.h - WidgetController 基类
  • Source/Aura/Public/UI/WidgetController/OverlayWidgetController.cpp - UI 绑定示例
  • Source/Aura/Public/UI/WidgetController/AttributeMenuWidgetController.cpp - 动态属性菜单
  • Source/Aura/Public/UI/HUD/AuraHUD.h - HUD 工厂

本文档基于 2024-05-30 对三个参考项目的深度代码分析编写。 所有推荐模式均已在对应项目中验证可行。