第一次提交
This commit is contained in:
254
GAS_AttributeSystem_Notes.md
Normal file
254
GAS_AttributeSystem_Notes.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# GAS 属性系统实现记录(PHY)
|
||||
|
||||
> 说明:本文记录在本项目中,为古风游戏(四维:臂力/根骨/内息/身法)搭建 GAS 属性体系、派生属性、职业初始化、以及服务器端定时回复(回血/回内)等功能的实现过程。
|
||||
>
|
||||
> 本项目模块不对外暴露,因此代码全部放在 `Source/PHY/Private` 内(AttributeSet/GE/MMC/GameplayTags 等)。
|
||||
|
||||
---
|
||||
|
||||
## 0. 总体目标
|
||||
|
||||
- 基础属性(Primary):
|
||||
- **Strength(臂力)**
|
||||
- **Constitution(根骨)**
|
||||
- **InnerBreath(内息)**
|
||||
- **Agility(身法)**
|
||||
- 其他属性由四维派生(MMC 计算)或由装备/功法 GE 附加。
|
||||
- 不对外提供公共模块 API:代码全部在 `Private`。
|
||||
|
||||
---
|
||||
|
||||
## 1. GAS 组件挂载位置与初始化
|
||||
|
||||
### 1.1 AbilitySystemComponent 放在 PlayerState
|
||||
|
||||
- 在 `APHYPlayerState` 的构造函数中创建:
|
||||
- `UAbilitySystemComponent* AbilitySystemComponent`
|
||||
- `UPHYAttributeSet* AttributeSet`
|
||||
- 设置复制:
|
||||
- `AbilitySystemComponent->SetIsReplicated(true)`
|
||||
- `AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Minimal)`(适合 PlayerState)
|
||||
|
||||
相关文件:
|
||||
- `Source/PHY/Private/Gameplay/Player/PHYPlayerState.cpp`
|
||||
|
||||
### 1.2 Character 初始化 GAS:Owner=PlayerState,Avatar=Character
|
||||
|
||||
在 `APHYPlayerCharacter`:
|
||||
- `PossessedBy()`(服务器)调用 `InitializeGAS()`
|
||||
- `OnRep_PlayerState()`(客户端)也调用 `InitializeGAS()`
|
||||
|
||||
初始化逻辑(核心):
|
||||
- `ASC->InitAbilityActorInfo(PlayerState, this)`
|
||||
- 服务器:
|
||||
- Apply `UPHYGE_InitPrimary`(设置四维初值)
|
||||
- Apply `UPHYGE_DerivedAttributes`(无限期派生属性:Override + MMC)
|
||||
- 设置资源/当前值:
|
||||
- `Health = MaxHealth`
|
||||
- `InnerPower = MaxInnerPower`
|
||||
|
||||
相关文件:
|
||||
- `Source/PHY/Private/Character/PHYPlayerCharacter.h/.cpp`
|
||||
|
||||
---
|
||||
|
||||
## 2. AttributeSet(全部在 Private)
|
||||
|
||||
### 2.1 AttributeSet 位置
|
||||
|
||||
- `Source/PHY/Private/AbilitySystem/Attributes/PHYAttributeSet.h`
|
||||
- `Source/PHY/Private/AbilitySystem/Attributes/PHYAttributeSet.cpp`
|
||||
|
||||
### 2.2 属性分组
|
||||
|
||||
#### Primary(基础四维)
|
||||
- `Strength`
|
||||
- `Constitution`
|
||||
- `InnerBreath`
|
||||
- `Agility`
|
||||
|
||||
#### Vitals(生命)
|
||||
- `Health`
|
||||
- `MaxHealth`
|
||||
|
||||
#### Resource(资源)
|
||||
- `InnerPower`
|
||||
- `MaxInnerPower`
|
||||
|
||||
#### Derived(示例派生)
|
||||
- `MoveSpeed`
|
||||
- `PhysicalAttack`
|
||||
- `PhysicalDefense`
|
||||
|
||||
#### Secondary(二级属性)
|
||||
- `Tenacity`(韧性)
|
||||
- `CritChance`(暴击率 0~1)
|
||||
- `CritDamage`(暴击伤害倍率 >=1)
|
||||
- `DodgeChance`(闪避 0~1)
|
||||
- `HitChance`(命中 0~1)
|
||||
- `ParryChance`(招架 0~1)
|
||||
- `CounterChance`(反击 0~1;业务逻辑要求闪避/招架成功后再判定)
|
||||
- `ArmorPenetration`(穿甲 0~1;目前字段存在,数值来源更多偏装备/功法)
|
||||
- `DamageReduction`(免伤 0~1)
|
||||
- `LifeSteal`(吸血 0~1;目前字段存在,数值来源更多偏装备/功法)
|
||||
- `HealthRegenRate`(生命回复/秒)
|
||||
- `InnerPowerRegenRate`(内力回复/秒)
|
||||
|
||||
### 2.3 Clamp 与复制
|
||||
|
||||
在 AttributeSet 内实现:
|
||||
- `PreAttributeChange`:
|
||||
- `Health` / `InnerPower` clamp 到 `[0, Max]`
|
||||
- 概率类 clamp 到 `[0, 1]`
|
||||
- `CritDamage` clamp `>= 1`
|
||||
- `PostGameplayEffectExecute`:
|
||||
- 对关键属性再兜底 clamp
|
||||
- 完整实现:
|
||||
- `OnRep_XXX`
|
||||
- `GetLifetimeReplicatedProps` + `DOREPLIFETIME_CONDITION_NOTIFY`
|
||||
|
||||
---
|
||||
|
||||
## 3. 派生属性计算(MMC)
|
||||
|
||||
### 3.1 MMC 放置位置
|
||||
|
||||
`Source/PHY/Private/AbilitySystem/MMC/`
|
||||
|
||||
### 3.2 已实现的 MMC(示例)
|
||||
|
||||
#### 基础派生
|
||||
- `UPHY_MMC_MaxHealth`:`MaxHealth = 100 + Constitution * 25`
|
||||
- `UPHY_MMC_MoveSpeed`:`MoveSpeed = 600 + Agility * 2`
|
||||
- `UPHY_MMC_PhysicalAttack`:`PhysicalAttack = 10 + Strength * 2`
|
||||
- `UPHY_MMC_PhysicalDefense`:`PhysicalDefense = 5 + Constitution * 1.5`
|
||||
|
||||
#### 二级属性派生(示例系数,后续建议数据化)
|
||||
- `UPHY_MMC_MaxInnerPower`:`MaxInnerPower = 100 + InnerBreath * 20`
|
||||
- `UPHY_MMC_Tenacity`:`Tenacity = InnerBreath * 1`
|
||||
- `UPHY_MMC_CritChance`:`CritChance = 0.05 + Agility * 0.002 (clamp 0..1)`
|
||||
- `UPHY_MMC_CritDamage`:`CritDamage = 1.5 + Strength * 0.005 (>=1)`
|
||||
- `UPHY_MMC_DodgeChance`:`DodgeChance = 0.02 + Agility * 0.002`
|
||||
- `UPHY_MMC_HitChance`:`HitChance = 0.9 + Agility * 0.001`
|
||||
- `UPHY_MMC_ParryChance`:`ParryChance = 0.03 + Strength * 0.001`
|
||||
- `UPHY_MMC_CounterChance`:`CounterChance = 0.1 + Agility * 0.001`
|
||||
- `UPHY_MMC_DamageReduction`:`DamageReduction = Constitution * 0.001`
|
||||
- `UPHY_MMC_HealthRegenRate`:`HealthRegenRate = Constitution * 0.1`
|
||||
- `UPHY_MMC_InnerPowerRegenRate`:`InnerPowerRegenRate = InnerBreath * 0.15`
|
||||
|
||||
> 注:部分属性如穿甲/吸血更适合由装备/功法 GE 直接加成,而非完全从四维硬算。
|
||||
|
||||
---
|
||||
|
||||
## 4. GameplayEffect(初始化 + 派生)
|
||||
|
||||
### 4.1 初始化四维:`UPHYGE_InitPrimary`
|
||||
|
||||
- 文件:`Source/PHY/Private/AbilitySystem/Effects/PHYGE_InitPrimary.h/.cpp`
|
||||
- 类型:Instant
|
||||
- 用 `SetByCaller` 写入四维(复用同一个 GE 支持所有职业)
|
||||
|
||||
SetByCaller Tag(NativeGameplayTags 管理):
|
||||
- `Data.Init.Primary.Strength`
|
||||
- `Data.Init.Primary.Constitution`
|
||||
- `Data.Init.Primary.InnerBreath`
|
||||
- `Data.Init.Primary.Agility`
|
||||
|
||||
### 4.2 派生属性:`UPHYGE_DerivedAttributes`
|
||||
|
||||
- 文件:`Source/PHY/Private/AbilitySystem/Effects/PHYGE_DerivedAttributes.h/.cpp`
|
||||
- 类型:Infinite
|
||||
- Modifiers:全部使用 `Override + MMC`
|
||||
- 包含 `MaxHealth/MoveSpeed/PhysicalAttack/PhysicalDefense`
|
||||
- 包含新增二级属性/资源上限(如 `MaxInnerPower`、暴击等)
|
||||
|
||||
---
|
||||
|
||||
## 5. GameplayTags 组织(集中管理,避免硬编码 FName)
|
||||
|
||||
### 5.1 Init 属性 Tag
|
||||
|
||||
- `Source/PHY/Private/GameplayTags/InitAttributeTags.h/.cpp`
|
||||
|
||||
### 5.2 Regen Tag
|
||||
|
||||
- `Source/PHY/Private/GameplayTags/RegenTags.h/.cpp`
|
||||
|
||||
### 5.3 ini 配置
|
||||
|
||||
- 新增/维护:`Config/DefaultGameplayTags.ini`
|
||||
- 包含 `Data.Init.Primary.*`
|
||||
- 包含 `Data.Regen.*`
|
||||
|
||||
---
|
||||
|
||||
## 6. 职业/门派初始属性(全局配置)
|
||||
|
||||
### 6.1 职业枚举
|
||||
|
||||
- `Source/PHY/Private/AbilitySystem/PHYCharacterClass.h`
|
||||
|
||||
### 6.2 DataAsset:全局职业默认值表
|
||||
|
||||
- `Source/PHY/Private/AbilitySystem/PHYClassDefaults.h`
|
||||
- `UPHYClassDefaults`:
|
||||
- `FallbackPrimary`
|
||||
- `Classes[]`:每个职业对应一套 `FPHYPrimaryAttributes`
|
||||
|
||||
### 6.3 配置位置:GameInstance
|
||||
|
||||
考虑到 `ClassDefaults` 是全局数据,不应放在每个 Character 上:
|
||||
- `UPHYGameInstance` 增加 `ClassDefaults` 引用
|
||||
- `GetClassDefaults()`
|
||||
|
||||
文件:
|
||||
- `Source/PHY/Private/Gameplay/PHYGameInstance.h/.cpp`
|
||||
|
||||
使用方式:
|
||||
- 在编辑器中的项目 GameInstance 蓝图(`DefaultEngine.ini` 指定的 `GameInstance_Default`)里配置 `ClassDefaults` 资产。
|
||||
|
||||
---
|
||||
|
||||
## 7. 服务器端定时回复(方案 B:代码驱动)
|
||||
|
||||
> 选择方案 B:不使用 Period GE,而使用 **服务器 Timer + Instant GE**。
|
||||
|
||||
### 7.1 Regen 每跳 GE:`UPHYGE_RegenTick`
|
||||
|
||||
- 文件:`Source/PHY/Private/AbilitySystem/Effects/PHYGE_RegenTick.h/.cpp`
|
||||
- 类型:Instant
|
||||
- 使用 SetByCaller:
|
||||
- `Data.Regen.Health`(加到 Health)
|
||||
- `Data.Regen.InnerPower`(加到 InnerPower)
|
||||
|
||||
### 7.2 Character 计时器逻辑
|
||||
|
||||
在 `APHYPlayerCharacter`:
|
||||
- 属性:`RegenInterval`(默认 1 秒)
|
||||
- 在 `InitializeGAS()` 服务器端启动 Timer:
|
||||
- `SetTimer(RegenTimerHandle, RegenTick, RegenInterval, true)`
|
||||
- `RegenTick()`:
|
||||
- `HealthDelta = HealthRegenRate * RegenInterval`
|
||||
- `InnerPowerDelta = InnerPowerRegenRate * RegenInterval`
|
||||
- Apply `UPHYGE_RegenTick`(SetByCaller 写入本次增量)
|
||||
|
||||
> 后续可拓展:脱战回复/坐下打坐/战斗中禁回等,均通过 GameplayTag 或状态判断来控制 `RegenTick()` 是否执行。
|
||||
|
||||
---
|
||||
|
||||
## 8. 代码风格/工程注意事项
|
||||
|
||||
### 8.1 UTF-8 BOM 引发的编译/IDE 问题
|
||||
|
||||
过程中多次遇到文件头 BOM 导致的解析错误(如 `无法解析符号 ''`)。
|
||||
已对相关文件移除 BOM(例如 PlayerState / PlayerCharacter / GameInstance 等)。
|
||||
|
||||
---
|
||||
|
||||
## 9. 下一步建议(可选)
|
||||
|
||||
- 将二级属性派生系数数据化(DataAsset/CurveTable),减少硬编码常量。
|
||||
- 装备/功法:用 GE 直接对二级属性加成(穿甲/吸血等更适合走装备词条)。
|
||||
- 战斗结算库:统一命中/闪避/招架/反击触发顺序与公式。
|
||||
- Regen 增加“脱战 N 秒后生效”等状态控制(GameplayTag 驱动)。
|
||||
|
||||
Reference in New Issue
Block a user