摄像机区域的架构改动

This commit is contained in:
2026-05-15 14:47:24 +08:00
parent 1b37297585
commit f264329751
3591 changed files with 1687228 additions and 446503 deletions

View File

@@ -0,0 +1,324 @@
# 手动测试 08 · 敌人系统
> **测试类型**Unity Editor 手动测试Play Mode
> **覆盖模块**`BaseGames.Enemies`、`BaseGames.Enemies.AI`、`BaseGames.Enemies.Navigation`
> **依赖组件**`EnemyBase`、`EnemyCombat`、`EnemyMovement`、`BehaviorDesigner`、`PathBerserker2d`
> **场景要求**:已烘焙 NavSurface至少包含近战/远程/飞行三种敌人各一只
---
## 快速工具
| 工具 | 用途 | 菜单路径 |
|------|------|----------|
| **Place Enemy (Basic)** | 放置带 EnemyBase、EnemyStats、HurtBox、HitBox_Body 的基础敌人;多次调用可摆放多种变体,然后手动调整组件 | `BaseGames → Scene → Place → Enemy (Basic)` |
| **Place Nav Surface** | 在场景中放置 PathBerserker2d NavSurface 对象 | `BaseGames → Scene → Place → Nav Surface` |
| **Place Ground Platform** | 放置地面平台Layer=Ground | `BaseGames → Scene → Place → Ground Platform` |
> **NavSurface 烘焙**:在 Inspector 中找到 `NavSurface` 组件,点击 **Bake** 按钮(无对应菜单命令)。
> **注意**PlayModeDebugOverlay 已移除。运行时状态效果测试请通过配置带效果的敌人攻击,或代码调用 `StatusEffectManager.Apply()`。
**典型工作流**
1. 测试前:`Place → Ground Platform` 生成地面 + `Place → Enemy (Basic)` 放置近战 / 远程 / 飞行三种敌人(多次调用,手动调整组件和配置)。
2. **Add Enemy Variants**`Place → Enemy (Basic)` 多次,分别调整 `EnemyStats` 和行为树为远程 / 飞行变体。
3. Inspector NavSurface → **Bake** 烘焙寻路数据(相比手动查找 Inspector 更直接)。
4. 状态效果测试(`MT-ENEMY-04`):配置带毒/燃烧效果的敌人攻击,或通过代码调用;观察 VFX 变化和 Console 事件。
---
## 目录
1. [NavSurface 烘焙检查](#1-navsurface-烘焙检查)
2. [MT-ENEMY-01近战敌人 AI 基础行为](#mt-enemy-01近战敌人-ai-基础行为)
3. [MT-ENEMY-02远程敌人RangedEnemy](#mt-enemy-02远程敌人rangedenemy)
4. [MT-ENEMY-03飞行敌人FlyingEnemy](#mt-enemy-03飞行敌人flyingenemy)
5. [MT-ENEMY-04敌人霸体与击退](#mt-enemy-04敌人霸体与击退)
6. [MT-ENEMY-05敌人死亡与掉落](#mt-enemy-05敌人死亡与掉落)
7. [MT-ENEMY-06敌人配额管理](#mt-enemy-06敌人配额管理)
8. [MT-ENEMY-07Boss 战切换流程](#mt-enemy-07boss-战切换流程)
---
## 1. NavSurface 烘焙检查
PathBerserker2d 的寻路**完全依赖烘焙数据**,未烘焙时敌人原地站立无响应。
> **🔧 敌人场景快速搭建**
>
> 1. `BaseGames → Scene → Place → Ground Platform` 生成地面 + `Place → Player` 放置玩家(若尚未搭建)
> 2. `BaseGames → Scene → Place → Enemy (Basic)` 多次调用,放置近战 / 远程 / 飞行三种敌人:
> - **MeleeEnemy**保持默认配置EnemyBase + EnemyStats + EnemyMovement + HurtBox
> - **RangedEnemy**:手动添加 `ShootPoint` 子 GameObject调整 EnemyStats 为远程变体 SO
> - **FlyingEnemy**:手动修改 Rigidbody2D → Kinematic`gravityScale = 0`
>
> 三只敌人均需在 Inspector 中绑定 Behavior Designer 行为树资产(`BehaviorTree._externalBehavior` 字段)
> 3. Inspector NavSurface 组件 → 点击 **Bake** 烘焙近战 + 远程敌人的寻路数据
>
> **注意**`FlyingEnemy` 无需 NavSurface 寻路;`RangedEnemy` 需要 NavSurface 才能进行保距移动。
**检查步骤**
1. 在测试场景中选中挂有 `NavSurface` 组件的 GameObject
2. Inspector 中找到 `NavSurface` 组件,点击 **Bake**
3. Scene 视图中地面显示**蓝绿色半透明网格** → 烘焙成功
**提示**:若 Gizmo 不可见,点击 Scene 视图右上角 `Gizmos` → 确认 PathBerserker2d 相关项已勾选。
---
## MT-ENEMY-01近战敌人 AI 基础行为
**目的**:验证近战敌人的巡逻 → 追击 → 攻击 → 返回 Behavior Designer 行为树。
> **🔧 前置检查**
> - `Place → Enemy (Basic)` 已放置 `MeleeEnemy` 并挂载所有必要组件
> - Inspector 中 `BehaviorTree._externalBehavior` 字段已绑定行为树资产(手动拖入)
> - NavSurface 已烘焙Inspector → Bake 按钮)
### 步骤
**步骤 A巡逻行为**
1. 进入 Play Mode
2. 玩家保持在敌人**视野范围外**(超过 `detectionRange`
3. 观察敌人
**预期**
- 敌人在巡逻点之间来回移动
- 播放 `Walk`/`Patrol` 动画
- Console 无 PathBerserker2d 寻路错误
**步骤 B追击行为**
1. 玩家进入敌人视野(`detectionRange` 内且无遮挡物)
2. 观察敌人反应
**预期**
- 敌人停止巡逻,转向玩家方向
- 播放 `Run`/`Chase` 动画
- 以最优路径追击玩家PathBerserker2d 动态路径)
**步骤 C攻击行为**
1. 玩家进入敌人攻击范围(`attackRange` 内)
2. 观察敌人攻击
**预期**
- 播放攻击动画Behavior Designer 行为树触发攻击节点)
- `EnemyCombat.HitBox` 激活,若玩家在判定范围内触发伤害
- 攻击后进入冷却(`attackCooldown`
**步骤 D掉失目标后返回**
1. 玩家跑出敌人追击范围(`chaseRange` 外)
2. 观察敌人
**预期**
- 敌人停止追击,返回初始位置或巡逻路径
- 返回后恢复巡逻动画
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 巡逻动画 | 视野外敌人来回巡逻 | ☐ |
| 追击切换 | 玩家进入视野后立即追击 | ☐ |
| 攻击命中 | 攻击范围内玩家 HP 减少 | ☐ |
| 返回巡逻 | 丢失目标后返回初始位置 | ☐ |
| 无寻路错误 | Console 无 PathBerserker2d 相关 Error | ☐ |
---
## MT-ENEMY-02远程敌人RangedEnemy
**目的**:验证 `RangedEnemy` 的投射物发射、移动闪避、最优射击位置。
> **🔧 前置检查**
> - `BaseGames → Scene → Place → Enemy (Basic)` 已放置 `RangedEnemy`(调整 EnemyStats 为远程变体,位置 x=8
> - Inspector 中为 `RangedEnemy` 配置行为树资产(保距 + LOS 检测 + 发射节点)
> - `RangedEnemy._shootPoint` 子 Transform 已手动添加
> - 场景有静止障碍物(`Place → Obstacle (Static)`)以便观察子弹碰撞
### 步骤
1. 确认测试场景中有 `RangedEnemy` 实例(挂有 `EnemyCombat` 组件)
2. 进入 Play Mode玩家接近远程敌人
**步骤 A保持距离**
**预期**:远程敌人尝试保持在 `preferredDistance` 附近,玩家靠近时后退。
**步骤 B发射投射物**
**预期**
-`shootRange` 内发射投射物(`LinearProjectile``ArcProjectile`
- 投射物从 `_shootPoint` Transform 位置发出
- 命中玩家触发伤害
**步骤 CLOS视线检测**
1. 让玩家躲在墙壁后面(无视线)
2. 观察远程敌人是否仍然发射
**预期**无视线时敌人停止发射LOS 检测生效)。
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 保持距离 | 玩家靠近时后退 | ☐ |
| 发射投射物 | 视线内发射子弹命中玩家 | ☐ |
| LOS 遮挡 | 墙后无视线时停止发射 | ☐ |
---
## MT-ENEMY-03飞行敌人FlyingEnemy
**目的**:验证 `FlyingEnemy` 的空中移动、俯冲攻击、不受地面 NavSurface 约束。
> **🔧 前置检查**
> - `BaseGames → Scene → Place → Enemy (Basic)` 已放置 `FlyingEnemy`(位置 (3,5,0)
> - `Rigidbody2D.gravityScale = 0``bodyType = Kinematic`(手动在 Inspector 设置)
> - 配置行为树资产(直线追击 + 俯冲攻击,无需 NavSurface
### 步骤
1. 确认场景有 `FlyingEnemy` 实例Kinematic RBgravityScale=0
2. 进入 Play Mode
**步骤 A空中悬停/巡逻**
**预期**
- 飞行敌人在空中自由移动,不受地形限制
- 可以穿越平台上下(不像地面敌人需要寻路绕路)
**步骤 B俯冲攻击**
**预期**
- 锁定玩家后俯冲攻击
- 攻击后飞回起始高度,继续攻击循环
**步骤 C不被地面碰撞阻挡**
1. 让飞行敌人在追击路径中有地形障碍
**预期**:飞行敌人从障碍物上方飞过(不被地面碰撞体阻挡)。
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 空中自由移动 | 不受地面寻路限制 | ☐ |
| 俯冲攻击 | 正确识别玩家位置并俯冲 | ☐ |
| 绕过地形 | 从障碍上方飞过 | ☐ |
---
## MT-ENEMY-04敌人霸体与击退
**目的**:验证 `EnemyPoiseComponent` 在普通攻击下保持动画,重攻击才打断。
### 步骤
**步骤 A普通连击不打断**
1. 对有较高霸体的敌人进行连击
**预期**:若连击伤害低于霸体 `breakLevel`,敌人动画**不被打断**,继续执行 AI 行为。
**步骤 B重攻击打断**
1. 对同一敌人使用 `BreakLevel` 高的攻击(如下劈 `DownAttack` 或特殊技能)
**预期**敌人进入受击硬直AI 行为树暂停。
**步骤 C击退效果**
1. 攻击有击退(`knockbackForce > 0`)的攻击
**预期**:敌人被击退一定距离(`knockbackForce` 方向与大小),不会穿墙。
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 普通攻击不打断 | 霸体保护时 AI 行为继续 | ☐ |
| 重攻击打断 | BreakLevel > Poise 时触发硬直 | ☐ |
| 击退物理 | 被击退后不穿越地形 | ☐ |
---
## MT-ENEMY-05敌人死亡与掉落
**目的**:验证敌人 HP 归零后的死亡流程、Geo 掉落、`LootResolver`
### 步骤
1. 将敌人 HP 降至 0
**预期**
- 死亡动画播放
- 死亡动画结束后 GameObject 从场景移除(或 `SetActive(false)` 归还对象池)
- `LootTableSO` 根据权重随机掉落 Geo 或其他物品
2. 在掉落的 Geo 上移动玩家
**预期**Geo 被拾取,玩家 `CurrentGeo` 增加HUD Geo 数量更新。
3. 重新进入场景(房间切换后返回)
**预期**:根据 `WorldStateRegistry` 配置,死亡敌人是否重生(可配置的一次性/可重生区别)。
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 死亡动画 | HP 归零后播放死亡动画 | ☐ |
| 清理 | 动画结束后 GameObject 消失或归池 | ☐ |
| Geo 掉落 | 掉落 Geo 可拾取HUD 更新 | ☐ |
| LootTable | 掉落物符合权重概率 | ☐ |
---
## MT-ENEMY-06敌人配额管理
**目的**:验证 `EnemyQuotaManager` 限制同屏激活敌人数量,防止性能劣化。
### 步骤
1. 打开 Inspector找到场景中的 `EnemyQuotaManager`
2. 记录当前 `maxActiveEnemies` 配置值(如 8
3. 进入 Play Mode触发大量敌人通过多个 EnemySpawner
**预期**
- 同屏激活的敌人不超过 `maxActiveEnemies`
- 超出配额的敌人保持待机Deactivate 或等待)
- 当已激活敌人死亡后,待机敌人激活补充
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 不超过配额 | 激活敌人数量 ≤ maxActiveEnemies | ☐ |
| 死亡后补充 | 敌人死亡后待机敌人激活 | ☐ |
---
## MT-ENEMY-07Boss 战切换流程
**目的**:验证 Boss 战触发的 GameState 切换Gameplay → BossFight、Boss 血条 UI 显示。
### 步骤
1. 进入有 Boss 触发器的场景或房间
2. 玩家进入 Boss 房间触发器
**预期**
- `EVT_BossFightStarted` 事件触发EventBusMonitor 可见)
- `GameManager` 状态切换到 `BossFight`
- Boss HP 血条 UI 出现(大型 HP 条 + Boss 名称文字)
- 背景音乐切换为 Boss 战曲目
3. 将 Boss HP 降至 0
**预期**
- `EVT_BossFightEnded` 事件触发(`victory = true`
- GameManager 切回 `Gameplay` 状态
- Boss 血条 UI 隐藏
- 胜利 VFX/音效播放
| 检查点 | 期望 | ✓ |
|--------|------|---|
| Boss 战触发 | 进入触发器后 GameState = BossFight | ☐ |
| Boss HP 条 | Boss 血条 UI 正确显示 | ☐ |
| BGM 切换 | 战斗音乐正确播放 | ☐ |
| Boss 死亡 | 胜利后状态恢复 Gameplay | ☐ |
| BossProgressTracker | Console 中 Boss 击败状态记录 | ☐ |