Files
zeling_v2/Docs/Verification/07_Manual_CombatSystem.md

359 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 手动测试 07 · 战斗系统
> **测试类型**Unity Editor 手动测试Play Mode
> **覆盖模块**`BaseGames.Combat`、`BaseGames.Parry`、`BaseGames.Combat.StatusEffects`
> **依赖组件**`HitBox`、`HurtBox`、`ShieldComponent`、`ParrySystem`、`StatusEffectManager`
> **场景要求**:测试场景含玩家 + 至少一只敌人Physics2D Layer 矩阵已配置
---
## 快速工具
| 工具 | 用途 | 菜单路径 |
|------|------|----------|
| **Check Physics2D Layer Matrix** | 一键检查层碰撞矩阵配置,输出 ✅/❌ 报告 | `BaseGames → Tools → Physics2D Layer Matrix → Check` |
| **Auto Fix Physics2D Layer Matrix** | 对所有错误层对自动调用 `Physics2D.IgnoreLayerCollision()` 并持久化 | `BaseGames → Tools → Physics2D Layer Matrix → Auto Fix` |
| **Place Enemy (Basic)** | 放置带 HurtBox、HitBox_Body 和 EnemyStats 的基础敌人(护盾测试需手动再添加 ShieldComponent | `BaseGames → Scene → Place → Enemy (Basic)` |
| **Place Obstacle (Static)** | 放置静止障碍物(投射物测试挡墙) | `BaseGames → Scene → Place → Obstacle (Static)` |
> **注意**PlayModeDebugOverlay 已移除。Play Mode 运行时调试请利用 Inspector 直接修改字段,或通过代码调用施加状态效果(见方式 C
**典型工作流**
1. 测试前:`BaseGames → Tools → Physics2D Layer Matrix → Check` 一键确认矩阵,若有红项立即 **Auto Fix**,无需手动翻 Project Settings。
2. `MT-COMBAT-04` 护盾:`Place → Enemy (Basic)` 放置敌人Inspector 中手动添加 `ShieldComponent`,进入 Play Mode 直接攻击。
3. `MT-COMBAT-06` 状态效果:通过代码或配置有状态效果的敌人攻击触发(见下方方式 A/B/C
4. `MT-COMBAT-07` 投射物:`Place → Obstacle (Static)` 放置挡墙,观察投射物命中效果。
---
## 目录
1. [Physics2D 配置检查](#1-physics2d-配置检查)
2. [MT-COMBAT-01战斗管道基础](#mt-combat-01战斗管道基础)
3. [MT-COMBAT-02HitBox 激活时序](#mt-combat-02hitbox-激活时序)
4. [MT-COMBAT-03弹反系统](#mt-combat-03弹反系统)
5. [MT-COMBAT-04护盾系统](#mt-combat-04护盾系统)
6. [MT-COMBAT-05霸体Poise系统](#mt-combat-05霸体poise系统)
7. [MT-COMBAT-06状态效果集成](#mt-combat-06状态效果集成)
8. [MT-COMBAT-07投射物系统](#mt-combat-07投射物系统)
9. [MT-COMBAT-08碰撞冲突Clash系统](#mt-combat-08碰撞冲突clash系统)
---
## 1. Physics2D 配置检查
在开始战斗测试前,必须确认 Layer 碰撞矩阵:
**路径**`Edit → Project Settings → Physics 2D → Layer Collision Matrix`
| Layer A | Layer B | 应开启碰撞 |
|---------|---------|---------|
| `PlayerHitBox` | `EnemyHurtBox` | ✅ 开启 |
| `EnemyHitBox` | `PlayerHurtBox` | ✅ 开启 |
| `Player` | `Ground` | ✅ 开启 |
| `Enemy` | `Ground` | ✅ 开启 |
| `Projectile` | `EnemyHurtBox` | ✅ 开启 |
| `Projectile` | `PlayerHurtBox` | ✅ 开启 |
| `PlayerHitBox` | `PlayerHurtBox` | ❌ 关闭(不自伤) |
| `EnemyHitBox` | `EnemyHurtBox` | ❌ 关闭(不自伤) |
---
## MT-COMBAT-01战斗管道基础
**目的**:验证完整攻击链路:玩家攻击 → HitBox 触发 → DamageInfo 计算 → 敌人 HP 扣减。
> **🔧 资源准备**
>
> 此测试需要场景中同时存在玩家和至少一只敌人:
>
> 1. `BaseGames → Scene → Place → Player` 生成玩家;`Place → Ground Platform` 生成地面(若尚未搭建)
> 2. `BaseGames → Scene → Place → Enemy (Basic)` 放置带 HurtBox 的基础敌人
> 3. `BaseGames → Tools → Physics2D Layer Matrix → Check` 检查并按需 **Auto Fix** 层碰撞矩阵
>
> **最小手动步骤**:场景中必须有 Layer=`EnemyHurtBox` 的触发碰撞体(挂 `HurtBox`),以及 Layer=`PlayerHitBox` 的攻击碰撞体(挂 `HitBox`)。
### 步骤
1. 进入 Play Mode
2. 走到敌人附近(攻击范围内)
3. 按攻击键Z/J
**预期**
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 伤害数字弹出 | 屏幕出现伤害数字 FloatingText | ☐ |
| 敌人 HP 减少 | Inspector 中 `EnemyStats.CurrentHP` 减少 | ☐ |
| HitStop 停顿 | 命中瞬间短暂帧停顿(约 0.05-0.1s),有命中质感 | ☐ |
| HitFX 播放 | 命中点产生对应类型的击中特效(斩击/钝击等) | ☐ |
| EVT_HitConfirmed 触发 | EventBusMonitor 显示 `EVT_HitConfirmed` 频道触发 | ☐ |
| Console 无 Error | 0 个红色 Error | ☐ |
4. 让敌人攻击玩家
**预期**
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 玩家 HP 减少 | HUD HP 条正确减少 | ☐ |
| HurtState 触发 | 玩家进入受击硬直 | ☐ |
| 受击闪白 | 玩家 Sprite 短暂白色HurtFlash | ☐ |
---
## MT-COMBAT-02HitBox 激活时序
**目的**:验证 `HitBox` 只在攻击动画关键帧期间处于 Active 状态,防止持续判定。
### 步骤
1. 打开 `Window → Analysis → Physics Debugger`Unity 内置)
2. 勾选 `Show Colliders`,并设置 Active Colliders 的颜色(绿色)
3. 进入 Play Mode放慢时间在 Console 输入 `Time.timeScale = 0.1f` 或使用调试菜单)
4. 执行攻击动作,在 Scene 视图观察 HitBox Collider
**预期**
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 攻击帧前 HitBox | `HitBox.gameObject.activeSelf == false` | ☐ |
| 攻击关键帧 HitBox | HitBox 变为 Active绿色 Collider 出现) | ☐ |
| 攻击帧后 HitBox | HitBox 重新 Deactive | ☐ |
**Console 验证方式(替代方案)**
`HitBox.cs``OnTriggerEnter2D` 中已有调试日志,观察 Console 中 HitBox 触发时序是否仅在攻击帧。
---
## MT-COMBAT-03弹反系统
**目的**:验证 `ParrySystem` 的弹反窗口判定、成功/失败反馈。
### 步骤
**步骤 A弹反成功**
1. 等待敌人发动攻击
2. 在攻击**命中前 `parryWindow` 秒内**按弹反键(默认 Q
**预期**
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 玩家不扣血 | HP 保持不变 | ☐ |
| 敌人硬直 | 敌人进入 `parriedStunDuration` 秒硬直 | ☐ |
| ParryFlash VFX | 命中点产生弹反特效 | ☐ |
| `EVT_ParrySuccess` 触发 | EventBusMonitor 显示触发 | ☐ |
| Stats.ParryCount +1 | 调试窗口或 Inspector 中 ParryCount 增加 | ☐ |
**步骤 B弹反窗口外过早**
1. 提前 1 秒按弹反键,等待敌人攻击到来
**预期**:弹反失败,玩家正常受击扣血,无弹反 VFX。
**步骤 C弹反窗口外过晚**
1. 等待敌人攻击已命中后再按弹反键
**预期**:弹反无效(已受伤),无弹反 VFX。
**步骤 D不可弹反攻击Unblockable**
1. 找到标记为 `Unblockable``InteractionTag`)的敌人攻击
2. 在弹反窗口内按弹反键
**预期**:弹反无效,玩家正常受击,无弹反 VFX。
**步骤 E弹反冷却**
1. 成功弹反后立即再次按弹反键
**预期**:冷却期间(`parryCooldown`)弹反无效。
| 弹反结果 | 预期现象 | ✓ |
|---------|---------|---|
| 成功(窗口内) | 不扣血 + 敌人硬直 + ParryFlash | ☐ |
| 失败(过早) | 正常受击扣血,无特效 | ☐ |
| 失败(过晚) | 正常受击扣血,无特效 | ☐ |
| Unblockable 攻击 | 弹反无效 | ☐ |
| 冷却期 | 再次按弹反无反应 | ☐ |
---
## MT-COMBAT-04护盾系统
**目的**:验证 `ShieldComponent` 护盾先吸收伤害,耗尽后 HP 才减少,护盾恢复计时。
### 前提条件
- 玩家装备含护盾护符(`ShieldComponent` 初始化,`ShieldHP > 0`
### 步骤
1. 确认 Inspector 中 `ShieldComponent.CurrentShieldHP` 为满值
2. 让敌人攻击玩家(伤害小于护盾值)
**预期**:护盾 HP 减少,玩家 HP 不变。
3. 继续承受伤害直到护盾耗尽
**预期**:护盾耗尽(`ShieldHP == 0`),护盾破碎 VFX/音效播放,后续攻击直接扣 HP。
4. 停止受击,等待 `shieldRecoveryDelay`
**预期**:护盾开始恢复,逐步回满。
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 护盾先吸收伤害 | 护盾耗尽前 HP 不减少 | ☐ |
| 护盾耗尽 | ShieldHP == 0ShieldIsBroken == true | ☐ |
| 耗尽后正常受伤 | 护盾破碎后攻击直接扣 HP | ☐ |
| 护盾恢复 | 停止受击后护盾逐步回满 | ☐ |
---
## MT-COMBAT-05霸体Poise系统
**目的**:验证 `PoiseComponent` 防止低优先级攻击打断高优先级动作。
### 步骤
**步骤 A普通攻击不打断霸体**
1. 进入攻击动作Attack3 动画)
2. 此时让霸体值足够(`currentPoise >= breakLevel of attack`)的敌人攻击玩家
**预期**:攻击动作**不被打断**`HurtState` 未触发(霸体值保护)。
**步骤 B重攻击打断霸体**
1. 找到攻击 `BreakLevel` 高于玩家 `Poise` 的敌人Boss 重击或特殊攻击)
2. 让其攻击玩家
**预期**`HurtState` 触发,攻击动作被打断,霸体值减少。
**步骤 C霸体恢复**
1. 玩家停止受击(不再被攻击),等待 `poiseRecoveryRate` 恢复
**预期**Inspector 中 `PoiseComponent.CurrentPoise` 逐步恢复至 `maxPoise`
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 普通攻击不打断 | 霸体充足时动作不中断 | ☐ |
| 重攻击打断 | BreakLevel > Poise 时触发 HurtState | ☐ |
| 霸体恢复 | 停止受击后逐步回满 | ☐ |
---
## MT-COMBAT-06状态效果集成
**目的**:在 Play Mode 中验证 StatusEffect 与 MonoBehaviour 的集成Tick 逻辑、VFX 显示)。
> **🔧 触发状态效果(三种方式)**
>
> **方式 A — 带状态效果的敌人攻击**
>
> 在敌人的攻击 `HitBox` 上配置 `_applyStatusEffect``StatusEffectSO` 引用 FireEffect / PoisonEffect让敌人打到玩家后自动施加
>
> **方式 C — 代码直接调用**
>
> ```csharp
> // 在场景内任意 MonoBehaviour 中调用Play Mode
> var sem = FindFirstObjectByType<StatusEffectManager>();
> sem?.Apply(poisonEffectSO, 3); // 施加 3 层 Poison
> ```
### 步骤(通过配置敌人或代码触发效果)
**Poison中毒测试**
1. 使玩家或敌人受到 Poison 状态效果(配置带毒敌人攻击,或代码调用 `sem?.Apply(poisonEffectSO, 3)`
2. 观察绿色粒子特效
**预期**
-`tickInterval` 秒扣减 `tickDamage` HP
- 绿色 VFX 粒子持续显示
- `duration` 秒后效果自动移除VFX 消失
**Fire燃烧测试**
1. 施加 Fire 效果,再施加 Freeze 效果
**预期**
- Fire 被 Freeze 互斥移除(`MutualExclusions` 生效)
- Console 无 NullReferenceException
**Stagger硬直测试**
1. 对敌人施加 Stagger 效果
**预期**
- 敌人进入硬直动画,`staggerDuration` 秒内无法移动/攻击
| 效果 | 检查点 | ✓ |
|------|--------|---|
| Poison | 定期 Tick 扣血 + 绿色粒子 + 到期自动移除 | ☐ |
| Fire | 施加 Freeze 后 Fire 自动移除 | ☐ |
| Stagger | 敌人硬直期间无法行动 | ☐ |
---
## MT-COMBAT-07投射物系统
**目的**:验证 `LinearProjectile``HomingProjectile``ArcProjectile` 三种投射物类型。
### 步骤
**LinearProjectile直线子弹**
1. 让远程敌人向玩家发射直线子弹
2. 观察子弹轨迹
**预期**:子弹沿直线运动,命中玩家扣血,命中地面消失(归还对象池)。
**HomingProjectile追踪子弹**
1. 触发追踪子弹(若场景有此类敌人)
2. 移动玩家改变位置
**预期**:子弹自动转向追踪玩家(`turnSpeed` 控制转向速率)。
**ParryableProjectile可弹反子弹**
1. 在子弹飞来时的弹反窗口内按弹反键
**预期**:子弹反向飞回,命中发射者并造成伤害。
| 检查点 | 期望 | ✓ |
|--------|------|---|
| Linear 直线运动 | 子弹直线飞行到目标或边界 | ☐ |
| Homing 追踪 | 子弹追踪玩家运动 | ☐ |
| 命中后归还对象池 | Hierarchy 中子弹 `SetActive(false)` | ☐ |
| Parryable 弹反 | 弹反后子弹反向 | ☐ |
---
## MT-COMBAT-08碰撞冲突Clash系统
**目的**:验证当玩家攻击与敌人投射物同时碰撞时,`ClashResolver` 正确处理冲突。
### 步骤
1. 在敌人发射子弹的同时玩家攻击命中子弹HitBox 与子弹 Collider 重叠)
2. 观察双方结果
**预期**
- 若玩家攻击力 >= 子弹 ClashBreakValue子弹被消除玩家无伤
- 若玩家攻击力 < 子弹 ClashBreakValue双方均受到部分伤害根据 `ClashConfigSO` 设置)
- Console 无 NullReferenceException
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 攻击胜出 | 子弹消除,玩家无伤 | ☐ |
| 攻击失败 | 双方受伤,无 Error | ☐ |
| Console 无 Error | 0 个 | ☐ |