引入属性、伤害管线

This commit is contained in:
2026-09-18 21:43:22 +08:00
parent 92e1ea0d55
commit ba25ec1926
108 changed files with 2920 additions and 720 deletions
@@ -0,0 +1,318 @@
# P5 Gameplay 玩法体系落地规划(类土豆兄弟 Brotato)
> **文档定位**:针对当前项目“性能优化/架构重,Gameplay 较少”在校招面试中的痛点,将项目从单纯的割草压测 Demo 升级为具备深度系统设计、复杂公式结算、规则可插拔的商业级“类土豆兄弟(Brotato)”完整玩法原型。
>
> 结合现有技术栈:**UGF + Luban 配置表 + 5层UI架构 + SimulationWorld(Burst + Job)**。
---
## 目录
1. [背景与核心设计目标](#1-背景与核心设计目标)
2. [总体架构分层与工程边界](#2-总体架构分层与工程边界)
3. [Phase 1: 复合属性修饰器管线与伤害结算系统](#3-phase-1-复合属性修饰器管线与伤害结算系统)
4. [Phase 2: 武器标签、羁绊与合成升阶系统](#4-phase-2-武器标签羁绊与合成升阶系统)
5. [Phase 3: 战斗触发器总线与状态/Buff系统](#5-phase-3-战斗触发器总线与状态buff系统)
6. [Phase 4: 局内波次经济循环与商店系统实战](#6-phase-4-局内波次经济循环与商店系统实战)
7. [Phase 5: 差异化角色特质系统(规则颠覆)](#7-phase-5-差异化角色特质系统规则颠覆)
8. [Phase 6: 机制化敌人与波次节奏导演](#8-phase-6-机制化敌人与波次节奏导演)
9. [阶段里程碑与推进检查表](#9-阶段里程碑与推进检查表)
10. [校招简历重塑与面试对线指南](#10-校招简历重塑与面试对线指南)
---
## 1. 背景与核心设计目标
### 1.1 面试痛点诊断
- **现状**:简历重构了 `SimulationWorld`,落地了 Burst + Job System,Android 压测 2k 敌人降耗 56.4%;但面试官全在问 Gameplay,因缺乏深度玩法而陷入被动。
- **面试官心理**:
1. 校招 Gameplay 岗核心看重:**能否承接复杂策划需求、业务抽象能力、数据结构与算法应用、面向对象与开闭原则(OCP)**。
2. 对单纯纯移动/无复杂状态的 Job 压测持防御态度(担心逻辑复杂后无法扩展)。
- **破局方案**:
- **保留底层性能作为技术壁垒**,展示“不仅能写底层高性能 Job,还能在上层支撑复杂多状态 Gameplay”。
- 落地土豆兄弟最具有代表性的核心机制:**深度属性网络、武器羁绊与合成、规则颠覆型角色特质、事件触发器与 Buff、波次经济商店**。
---
## 2. 总体架构分层与工程边界
为防止业务逻辑与现有的 Job/Burst 模拟层产生混乱耦合,确立以下分层原则:
```mermaid
flowchart TD
subgraph UI_Presentation ["表现与界面层 (Presentation)"]
UI["5层UI架构 (RawData/UseCase/Controller/Context/View)"]
FX["表现层 (Animator / Audio / VFX / DamageText)"]
end
subgraph Gameplay_Logic ["Gameplay 逻辑主控层 (Managed C#)"]
RoleTrait["角色特质系统 (Rule Interceptor)"]
AttrSys["属性修饰器管线 (Attribute Pipeline)"]
WeaponSys["武器槽位/羁绊/合成 (Weapon Synergy & Combine)"]
BuffSys["Buff与状态触发器总线 (Event Dispatcher & Buffs)"]
ShopSys["商店事务与波次经济 (Economy & Wave Director)"]
end
subgraph Sim_Layer ["高性能物理与移动层 (Burst + Job System)"]
SimWorld["SimulationWorld"]
Jobs["移动 / 分离 / 空间哈希分桶 / 碰撞候选生成 (Broad Phase)"]
end
UI --> Gameplay_Logic
Gameplay_Logic --> SimWorld
SimWorld -->|命中事件缓冲区 / 坐标输出| Gameplay_Logic
Gameplay_Logic --> FX
```
1. **SimulationWorld 保持纯粹**:
- 负责:空间哈希、宽相碰撞筛选、集群移动分离、投射物飞行轨迹。
- 绝不引入:托管对象、UI 回调、复杂 Buff 状态机。
2. **Gameplay 逻辑层(托管)掌管结算**:
- 消费 Simulation 输出的命中对(Collision Pair),执行伤害公式计算、Buff 挂载、击杀判定、事件派发。
3. **表现层与 UI 解耦**:
- UI 严格遵守现有的 5 层架构与 UGF 事件通信。
---
## 3. Phase 1: 复合属性修饰器管线与伤害结算系统
### 3.1 属性定义(15+ 维核心属性)
土豆兄弟的核心乐趣在于属性间的互斥与权衡取舍:
- **基础输出**:近战伤害(`MeleeDamage`)、远程伤害(`RangedDamage`)、元素伤害(`ElementalDamage`)、百分比增伤(`DamagePercent`)、攻击速度(`AttackSpeed`)、暴击率(`CritChance`)、攻击范围(`Range`)。
- **生存与机动**:最大生命(`MaxHp`)、生命回复(`HpRegen`)、生命偷取(`LifeSteal`)、护甲(`Armor`)、闪避(`Dodge`)、移动速度(`MoveSpeed`)。
- **特殊与经济**:工程学(`Engineering`,影响炮台/地雷)、收获(`Harvesting`,波次利息)、幸运(`Luck`,箱子掉率与商店品质)。
### 3.2 属性修饰器管线(Attribute Modifier Pipeline)
采用 **Base + Modifiers** 结构,结合 **Dirty Flag(脏标记缓存)** 避免高频 GC 与重算:
```csharp
public enum StatType
{
MaxHp, HpRegen, LifeSteal, DamagePercent, MeleeDamage, RangedDamage,
ElementalDamage, AttackSpeed, CritChance, Engineering, Range,
Armor, Dodge, MoveSpeed, Harvesting, Luck
}
public enum ModifierType
{
Flat = 100, // 固定值累加 (e.g. +5 近战伤害)
PercentAdd = 200, // 百分比累加 (e.g. +10% 伤害, 与其他同类相加)
PercentMult = 300 // 最终百分比独立乘区 (e.g. 伤害变为 1.5 倍)
}
public class StatModifier
{
public float Value { get; }
public ModifierType Type { get; }
public object Source { get; } // 来源:道具/武器/羁绊/特质
}
```
- **求值公式**:
$$\text{CurrentValue} = \left( (\text{Base} + \sum \text{Flat}) \times (1 + \sum \text{PercentAdd}) \right) \times \prod \text{PercentMult}$$
- **边界钳制(Clamping)**:
- 闪避硬上限:`Mathf.Min(Dodge, 0.60f)`(最高 60%)。
- 护甲减伤公式:$$\text{DamageMultiplier} = \frac{1}{1 + \frac{\text{Armor}}{15}} \quad (\text{若 } \text{Armor} \ge 0)$$
- 生命偷取:按次命中概率触发,内置全局 CD(如最多每秒偷取 10 次,防止霰弹枪/加特林瞬间回满)。
### 3.3 伤害结算流水线
```mermaid
flowchart LR
A[武器基础伤害] --> B[类型加成: 近战/远程/元素]
B --> C[百分比伤害放大: 1 + DamagePercent]
C --> D[暴击判定: 暴击倍率 1.5x ~ 2.0x]
D --> E[目标护甲折减]
E --> F[伤害飘字 & 扣血 & 吸血触发]
```
---
## 4. Phase 2: 武器标签、羁绊与合成升阶系统
### 4.1 核心机制规范
1. **6 槽位限制**:玩家最多同时装备 6 把武器,槽位满时不可拾取/购买新武器(除非替换或合成)。
2. **武器标签(Weapon Tags)**:
- 每种武器配置 1~2 个标签,如:
- 小刀:`[Blade, Precise]`
- 霰弹枪:`[Gun]`
- 扳手:`[Engineering, Blunt]`
- 火把:`[Primitive, Elemental]`
3. **阶梯羁绊(Set Bonuses)**:
- 当装备中同标签武器数量达到阈值(如 2 / 3 / 4 / 6)时,自动挂载全队属性修饰器:
- *原始(Primitive)*:2件 +3 HP / 3件 +6 HP / 6件 +15 HP。
- *刀剑(Blade)*:2件 +1 近战伤害 / 4件 +3 近战伤害 / 6件 +8 近战伤害 + 5% 吸血。
- *枪械(Gun)*:2件 +10 射程 / 4件 +25 射程 / 6件 +50 射程且自带穿透+1。
4. **武器合成(Tier Synthesis)**:
- 武器分 4 阶:白(Tier 1)/ 蓝(Tier 2)/ 紫(Tier 3)/ 红(Tier 4)。
- **合成规则**:在商店或背包中,两把同名、同品质的武器可点击合成,升阶为高一阶武器,空出一个槽位并增强属性(CD更短、射程更远、新增弹道或穿透)。
### 4.2 数据表设计(Luban)
- **`WeaponConfig_武器配置.xlsx` 扩展**:
- `Tags`:`list,int`(标签枚举列表)。
- `Tier`:`int`(品质 1~4)。
- `NextTierWeaponId`:`int`(下一级武器 ID)。
- `ScalingStat`:`int`(加成主属性:近战/远程/元素/工程)。
- `ScalingRatio`:`float`(加成系数,如 0.8)。
- **新建 `WeaponSynergyConfig_武器羁绊配置.xlsx`**:
- `TagId`:标签 ID。
- `RequiredCounts`:`list,int`(阶梯数量,如 `[2, 3, 4, 6]`)。
- `Modifiers`:`list,bean:StatModifierConfig`(对应各阶梯触发的属性修正)。
---
## 5. Phase 3: 战斗触发器总线与状态/Buff系统
### 5.1 战斗事件总线(Battle Event Bus)
建立高性能的直接委托事件驱动,覆盖战斗高频节点:
- `OnHit(HitContext ctx)`:命中敌人时(参数含受击者、伤害、是否暴击、伤害类型)。
- `OnDamaged(DamageContext ctx)`:自身受到伤害时。
- `OnKill(KillContext ctx)`:击杀敌人时。
- `OnWaveStart()` / `OnWaveEnd()`:波次起止。
### 5.2 经典 Buff 框架
```csharp
public abstract class BuffBase
{
public int BuffId { get; set; }
public float Duration { get; set; }
public int CurrentStacks { get; set; }
public int MaxStacks { get; set; }
public virtual void OnApply(Entity owner) { }
public virtual void OnTick(Entity owner, float deltaTime) { }
public virtual void OnRemove(Entity owner) { }
public virtual void OnStackAdded(Entity owner) { }
}
```
- **堆叠策略**:
1. `RefreshDuration`:刷新持续时间,层数 +1(如点燃、流血)。
2. `Additive`:独立计时器(复杂 Buff)。
3. `Override`:高强度替换低强度。
- **代表性状态实装**:
- **点燃(Burning)**:每 0.5s 造成一次伤害,伤害受玩家 `ElementalDamage` 加成,受击者死亡时向周围 2m 内敌人传播点燃。
- **击退(Knockback)**:击退位移,接入 `SimulationWorld` 的速度冲量或阻尼位移。
---
## 6. Phase 4: 局内波次经济循环与商店系统实战
### 6.1 核心流转与双重货币(Materials)
土豆兄弟没有将经验和金币分开,掉落的**绿晶(材料 Material)**同时兼具两种职能:
1. **拾取即获得局内经验**:达到阈值触发升级弹窗(局末加点或即时加点)。
2. **拾取存入临时金库**:作为波次结束后在商店消费的唯一货币。
3. **吸附清场**:波次计时结束(如 20s~60s)时,地图上未拾取的材料自动全图飞向玩家并结算入库。
### 6.2 收获机制(Harvesting)
- 每波次结束时:玩家获得等同于 `Harvesting` 点数的材料奖励。
- **复合增长(利息)**:若 `Harvesting > 0`,每波结束其自身永久增长 5%(向上取整),形成后期经济滚雪球。
### 6.3 商店系统落地(实战验证 5 层 UI 架构)
- **商品生成**:每轮提供 4 个展示槽(武器 + 道具混合抽取,概率受 `Luck` 属性加成)。
- **锁定槽位(Lock)**:玩家资金不足时可锁定某格商品,波次刷新时不被替换。
- **刷新(Reroll)与通胀**:
$$\text{RerollCost} = \text{BaseCost} + (\text{CurrentWave} \times 1) + (\text{RollTimesInThisShop} \times 2)$$
- **属性升级四选一(Level-up Draft)**:
- 每升 1 级积累 1 次加点机会。
- 随机抽取 4 项属性,并按概率随机赋予品质(普通/稀有/史诗/传奇,加成数值成倍放大)。
---
## 7. Phase 5: 差异化角色特质系统(规则颠覆)
### 7.1 为什么不做简单的数值增减?
如果只是“角色 A 攻击力 +10%,角色 B 生命 +20”,毫无架构含金量。土豆兄弟的精髓在于**打破既有规则**。
### 7.2 规则拦截器架构(Rule Interceptor Pattern)
通过接口/抽象组件挂载,在主流程核心逻辑的关键判断点注入拦截逻辑,遵循**开闭原则(OCP)**,拒绝在全局战斗代码中堆砌 `if (role == Bull)`:
```csharp
public interface IRuleInterceptor
{
// 是否允许装备指定类型武器
bool CanEquipWeapon(WeaponConfig weapon, int currentWeaponCount);
// 受到伤害时的特殊结算(公牛自爆)
void OnTakeDamageIntercept(ref DamageInfo damage);
// 波次结算时的特殊收益(和平主义者)
void OnWaveEndIntercept(WaveResult result);
}
```
### 7.3 实装 4 个极具代表性的角色
1. **独臂(One-Armed)**:
- 规则:`MaxWeaponSlots = 1`。
- 补偿:常驻 `AttackSpeed +200%`,`DamagePercent +100%`。
2. **公牛(Bull)**:
- 规则:`MaxWeaponSlots = 0`(不可携带任何武器)。
- 特质:受击时立即触发 360° 巨额范围爆炸,基础护甲 +15,生命秒回 +10。
3. **和平主义者(Pacifist)**:
- 规则:常驻 `DamagePercent = -100%`(击杀收益极低)。
- 特质:波次倒计时结束时,场上存活的敌人每有 1 只,转化为 1 份额外材料与经验。
4. **法师(Mage)**:
- 规则:所有攻击附带点燃效果,元素伤害加成翻倍,但近战/远程基础伤害扣减。
---
## 8. Phase 6: 机制化敌人与波次节奏导演
### 8.1 典型敌人机制(区别于纯移速僵尸)
1. **冲锋怪(Charger)**:进入玩家一定距离后停步蓄力闪红(Telegraph),随后进行高移速直线冲撞。
2. **图腾增益怪(Buffer)**:自身不攻击,环绕光环为其半径 4m 内的其他敌人提供移速与减伤 Buff。
3. **远程射击怪(Shooter)**:与玩家保持放风筝距离,周期性射出直线投射物。
4. **第 11 / 20 波 精英/Boss**:
- 拥有多阶段行为(Phase 1 环形弹幕,Phase 2 召唤小怪 + 追踪地雷),击杀必掉稀有道具宝箱。
---
## 9. 阶段里程碑与推进检查表
| 阶段 | 核心任务 | 涉及代码与模块 | 交付标准与回归 |
| :--- | :--- | :--- | :--- |
| **Phase 1** | **属性修饰器与伤害管线** | `StatModifier`, `AttributePipeline`, `PlayerData` 扩展, 伤害公式重构 | 单元测试覆盖所有修饰器加法/乘法与护甲折减公式,无浮点截断异常 |
| **Phase 2** | **武器标签羁绊与合成** | `WeaponSynergyManager`, `WeaponConfig` 扩展, 背包/槽位管理 | 6槽位限制生效,同标签激活被动,2把同名同阶武器合成升阶无资源泄露 |
| **Phase 3** | **事件触发器与Buff** | `BattleEventBus`, `BuffManager`, 点燃/击退/吸血实装 | 点燃每秒跳字传火正常,击退对接 Simulation 冲量,吸血有内置 CD 控制 |
| **Phase 4** | **波次经济与商店实战** | `ShopController` (5层UI), `Harvesting` 利息公式, 锁定与加点 | 倒计时清场自动吸附材料,商店刷新递增、锁定跨波次保存、4选1加点正常 |
| **Phase 5** | **规则颠覆角色特质** | `IRuleInterceptor`, 实装独臂/公牛/和平主义者 | 零硬编码支持独臂只能拿1把枪、公牛无法拿武器且受击自爆 |
| **Phase 6** | **机制敌人与波次配置** | 冲锋怪、图腾怪、Boss 弹幕、`WaveDirector` 表驱动 | 1~20 波次节奏平滑,精英怪出场带有危险警示圈与阶段切换 |
---
## 10. 校招简历重塑与面试对线指南
完成上述系统后,简历专业度将实现质的飞跃。
### 10.1 简历 Bullet Points 建议模板
- **主流程与 UI 架构**:
> 基于 Unity GameFramework 的 Procedure/FSM 搭建波次流转与选卡循环;为 Shop / LevelUp 设计落地 **RawData-UseCase-Controller-Context-View 五层 UI 架构**,解耦商品生成、锁定事务与展示渲染,提升高频迭代模块的复用性。
- **Gameplay 核心系统架构(重点突出)**:
> - **多维属性与伤害流水线**:设计支持 15+ 维派生属性的 **Attribute Modifier Pipeline**,通过脏标记(Dirty Flag)缓存避免频繁重算;落地包含基础增伤、暴击、护甲减免与内置 CD 吸血的复合伤害公式。
> - **武器羁绊与合成升阶**:实现基于**标签(Tags)聚合驱动的武器多维羁绊系统**与 6 槽位限制,支持同品质武器 2 合 1 升阶,解耦武器生命周期、模型挂点与发射器复用。
> - **事件驱动触发器与状态机**:搭建基于**观察者模式的战斗事件总线(OnHit / OnDamaged / OnKill)**与通用 Buff 状态机,实现点燃(DoT与传火扩散)、击退与状态互斥堆叠。
> - **开闭原则特质系统**:采用**规则拦截器(Rule Interceptor)模式**实现差异化角色特质,在零修改战斗主链路的前提下无缝支持“独臂(限制单武器/高攻速)”、“公牛(禁止武器/受击自爆)”等规则颠覆型玩法。
- **底层性能保障(底牌)**:
> - **Job System + Burst 并行模拟**:重构底层 `SimulationWorld`,将海量敌人移动分离、投射物模拟与网格空间哈希候选筛选接入 Burst 并行计算;在实机 2k 敌人同屏下 Tick 热路径耗时由 21.68 ms 降至 9.44 ms,为上层复杂 Gameplay 提供了宽裕的性能预算。
---
### 10.2 高频面试真题与最佳应答套路
#### Q1: “如果策划要加一个新角色‘受到伤害时分裂出小型炸弹,且无法使用枪械’,你的代码要改哪些地方?”
* **雷区回答**:在受到伤害的地方写 `if (role == BombMan)`,在穿装备的地方写 `if (weapon == Gun && role == BombMan) return false;`。
* **满分回答**:
> “在我的架构里完全不需要改动任何战斗核心代码。我设计了 `IRuleInterceptor` 特质机制:
> 1. 新建 `BombManTrait`,在 `CanEquipWeapon` 中检查武器标签若包含 `Gun` 则拦截返回 `false`。
> 2. 实现 `OnDamaged` 接口,订阅受击事件,在自身坐标实例化炸弹实体。
> 3. 在 Luban 的 `RoleConfig` 中为该角色绑定此特质 ID,角色进入战斗时自动挂载到上下文。核心逻辑完全对扩展开放、对修改关闭。”
#### Q2: “武器羁绊系统如果有 6 件套加成,玩家在战斗或商店里频繁换装/合成,属性怎么计算才不会错乱或产生高开销?”
* **满分回答**:
> “我采用了 **Tag 计数器 + 属性修饰器句柄 + 脏标记** 的设计:
> 1. 玩家持有 `Dictionary<WeaponTag, int>`。每次穿卸或合成武器,只对对应 Tag 计数做增减。
> 2. 羁绊触发器监听计数变更,当跨越 2/3/4/6 阈值时,向角色属性池派发或撤销带有唯一来源标记(Source)的 `StatModifier`。
> 3. 属性系统自身不每帧循环遍历修饰器,而是通过 `_isDirty` 标记在下次读取(如计算攻击伤害或生命最大值)时惰性重算并缓存结果,零 GC 且保证数据唯一真相源。”
#### Q3: “你的底层用 Burst 和 Job 处理了 2k 敌人,但上面这套复杂的 Buff、点燃传火、触发器全在托管堆,这两者怎么高效协同而不打破 Burst 约束?”
* **满分回答**:
> “这是我专门设计的**逻辑分层(Simulation vs Gameplay)边界**:
> 1. Job 和 Burst 只做高密度的**纯数据计算与宽相筛选(Broad Phase)**——如空间分桶、距离剔除、包围盒相交,并将发生碰撞的实体 ID 成对输出到 `NativeQueue<CollisionEvent>` 中。
> 2. 在主线程 Tick 阶段,由托管层的 `BattleManager` 一次性消费队列事件,执行复杂的 Gameplay 逻辑(判断防御、暴击、挂载 Buff、派发 C# 事件)。
> 3. 这样既享受了 Burst 处理大批量空间遍历与移动物理的高性能,又保住了上层 Gameplay 编写复杂业务时的灵活性与面向对象表达能力。”
+3 -1
View File
@@ -1,4 +1,4 @@
# 3D 类吸血鬼幸存者项目 Todo(GameMain 侧规划)
# 3D 类吸血鬼幸存者项目 Todo(GameMain 侧规划)
> 范围说明:本清单基于当前 `Assets/GameMain` 代码现状制定,未涉及 `Assets/GameFramework` 底层实现。
@@ -199,6 +199,8 @@
- 热更失败可自动回退,启动不中断。
## 6. P5 玩法目标对齐(与技术栈并行)
> 详细落地规划已输出至独立文档:[P5 Gameplay 玩法体系落地规划.md](P5%20Gameplay%20玩法体系落地规划.md)
- [ ] 武器系统补完:
- 自动攻击、多武器并存、同武器升级/进化。
- `Shop` 武器购买流程补完(当前已有 TODO)。