36 KiB
36 KiB
Zeling v2 · 全阶段验收测试文档
文档版本:1.0
覆盖范围:Phase 0 → Phase 4(Assets/Scripts/全量代码)
Unity 版本:2022.3 LTS
前置文档:Docs/Verification/Phase1_Verification_Guide.md(Phase 0/1 详细步骤,本文在此基础上新增 Phase 2–4 验收)
测试环境:Unity Editor Play Mode;测试房间场景(TestRoom.unity);Persistent 场景同时加载
目录
1. 测试前环境检查清单
在任意测试用例运行前,必须确认以下项全部通过:
| # | 检查项 | 验证方式 | 状态 |
|---|---|---|---|
| ENV-01 | Console 无红色 Error | Window → Console 错误数 = 0 |
☐ |
| ENV-02 | Addressables 已构建 | Window → Addressables → Groups → Build → New Build → Default |
☐ |
| ENV-03 | NavSurface 已烘焙 | Scene 视图可见蓝绿导航网格 Gizmo | ☐ |
| ENV-04 | Physics2D Layer 矩阵已配置 | Edit → Project Settings → Physics 2D,PlayerHitBox ↔ EnemyHurtBox 碰撞开启 |
☐ |
| ENV-05 | SO 事件资产存在 | Assets/Data/Events/ 下有 EVT_*.asset 文件 |
☐ |
| ENV-06 | Persistent 场景已加入 Build Settings | File → Build Settings,Persistent.unity 位于列表第一位 |
☐ |
| ENV-07 | Domain Reload 设置确认 | Edit → Project Settings → Editor → Enter Play Mode Options,勾选 Disable Domain Reload 时验证静态字典缓存行为 |
☐ |
注意:ENV-07 主要影响
BossSkillExecutor._wfsCache、WaitForSecondsCache等静态字典。若 Disable Domain Reload 开启,每次 Play Mode 前需手动触发清空(或保持默认:不禁用 Domain Reload)。
2. 阶段验收状态总览
| Phase | 代码状态 | 资产状态 | 验收状态 |
|---|---|---|---|
| P0 基础设施 | ✅ 完成 | ✅ 完成 | ☐ 待验 |
| P1 垂直切片 | ✅ 完成 | ⚠️ 需场景搭建 | ☐ 待验 |
| P2 核心玩法 | ✅ 完成 | ⚠️ VFX 资产待填充 | ☐ 待验 |
| P3 世界进程 | ✅ 完成 | ⚠️ Prefab 装配待完成 | ☐ 待验 |
| P4 内容完善 | ✅ 完成 | ✅ 完成 | ☐ 待验 |
3. P0 基础设施(快速回归)
此阶段已在 Phase1_Verification_Guide.md V1–V3 详细验证,此处仅快速回归确认。
| TC-ID | 测试项 | 步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P0-01 | asmdef 编译无错 | Unity 菜单 → Assets → Open C# Project,IDE 执行 Rebuild | 0 个编译错误 | ☐ |
| TC-P0-02 | ServiceLocator 注册/获取 | Play 进入 Persistent 场景,Console 搜索 [ServiceLocator] |
无 NullReferenceException,核心服务(SaveManager / ObjectPool / AudioManager / SceneLoader)注册成功 |
☐ |
| TC-P0-03 | SO 事件系统 | 在 Inspector 打开任意 EVT_*.asset,点击 Raise 按钮 |
Console 输出对应频道事件(开启 EventBusMonitor Window) | ☐ |
| TC-P0-04 | Addressables 加载 | Play Mode 下 AssetLoader.LoadAsync 通过 AddressKey 加载一个 Prefab |
Prefab 实例化无 InvalidKeyException |
☐ |
| TC-P0-05 | SaveManager 读写 | 调用 SaveManager.SaveAsync(slot:0),Exit Play Mode,再次 Enter Play Mode 调用 LoadAsync(0) |
存档文件存在于磁盘,加载后 Console 无 checksum 错误 | ☐ |
4. P1 核心系统(快速回归)
详细验证步骤见
Phase1_Verification_Guide.md,此处列出快速回归清单。
| TC-ID | 测试项 | 期望结果 | ☐ |
|---|---|---|---|
| TC-P1-01 | 输入系统 | WASD/方向键控制玩家移动,Space 跳跃,Z 攻击,Esc 暂停,无按键漏检 | ☐ |
| TC-P1-02 | Animancer FSM | Idle→Run→Jump→Fall 状态转换流畅,无动画卡帧 | ☐ |
| TC-P1-03 | PlayerMovement 物理 | 地面正常重力,跳跃弧线正确,土狼时间(Coyote)有效 | ☐ |
| TC-P1-04 | 战斗管道 | 攻击敌人触发伤害数字,敌人 HP 减少;受到敌人攻击,玩家 HP 减少 | ☐ |
| TC-P1-05 | 敌人寻路 AI | 敌人巡逻,玩家进入视野后追击并攻击 | ☐ |
| TC-P1-06 | 存档点完整流程 | 与 SavePoint 交互 → 触发存档 → 死亡 → 复活在存档点 → HP/灵力满值 | ☐ |
| TC-P1-07 | HUD 显示 | HP 条/灵力条/Geo 数量随游戏状态正确更新 | ☐ |
| TC-P1-08 | 相机系统 | 玩家进入 CameraTriggerZone 时相机平滑切换到目标房间 | ☐ |
5. P2 核心玩法扩展
5.1 玩家 FSM 完整状态
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P2-01 | DashState 冲刺 | 地面状态按冲刺键(默认 LeftShift) | 玩家水平快速位移,冲刺期间无敌帧生效(敌人攻击不触发 HurtState),结束后自然过渡 Idle/Run | ☐ |
| TC-P2-02 | AerialDashState 空中冲刺 | 跳跃后按冲刺键 | 空中水平冲刺,消耗空中冲刺次数;落地后次数重置 | ☐ |
| TC-P2-03 | WallSlideState 蹬墙下滑 | 跳跃后贴近墙壁按住方向 | 下滑速度减缓(wallSlideSpeed),Wall Slide 动画播放 |
☐ |
| TC-P2-04 | WallJumpState 蹬墙跳 | WallSlide 状态按跳跃键 | 玩家弹离墙壁(wallJumpForce),方向翻转 |
☐ |
| TC-P2-05 | HurtState 受击硬直 | 被攻击未被霸体保护 | 受击动画播放,持续 hurtDuration,期间不可输入 |
☐ |
| TC-P2-06 | DeadState 死亡冻结 | HP 归零 | 死亡动画,物理冻结(Rigidbody2D.constraints),死亡屏幕出现 | ☐ |
| TC-P2-07 | SpringState 使用灵泉 | 持有灵泉时按治疗键 | 治疗动画,HP 恢复,灵泉数量-1,不可打断(HurtState 优先级低于 SpringState 硬直期) | ☐ |
5.2 形态切换与武器系统
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P2-08 | 三形态切换 | 按形态切换键循环(Sky→Earth→Death→Sky) | 每次切换:玩家调色板更新(Palette Swap),武器 HitBox 伤害来源刷新,HUD 形态图标同步 | ☐ |
| TC-P2-09 | FormController 事件广播 | 切换形态后检查 Console(开启 EventBusMonitor) | EVT_FormChanged 频道触发,EVT_SkillSetChanged 频道触发 |
☐ |
| TC-P2-10 | WeaponManager 武器数据刷新 | 切换形态后攻击敌人 | 不同形态输出不同 DamageSource 的伤害值(需三形态武器 SO 伤害值不同) | ☐ |
| TC-P2-11 | SaveData 形态持久化 | 切换到 Earth 形态 → 存档 → 重载 | 重载后当前形态仍为 Earth | ☐ |
5.3 完整连击链
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P2-12 | 地面 3 段连击 | 连续按 3 次攻击(间隔在 Combo 窗口内) | 播放 Attack1 → Attack2 → Attack3 三段动画,第 3 段结束后返回 Idle,不可延续第 4 段 | ☐ |
| TC-P2-13 | 连击超时重置 | 按 1 次攻击后等待超时 | Combo 计数重置到 Attack1,再按攻击仍从头开始 | ☐ |
| TC-P2-14 | 空中攻击 | 跳跃后按攻击键 | 播放 AirAttack 动画,HitBox 激活(正前方) | ☐ |
| TC-P2-15 | 下劈(DownAttack) | 跳跃后向下+攻击 | 播放 DownAttack 动画,检测到下方敌人时反弹(trampolineForce) |
☐ |
| TC-P2-16 | 上劈(UpAttack) | 地面状态向上+攻击 | 播放 UpAttack 动画,HitBox 激活(正上方) | ☐ |
| TC-P2-17 | HitBox 激活时序 | 使用 Unity Physics Debugger 或 Console 输出 | HitBox 仅在动画攻击帧 Active,其他帧 Deactivate(无穿透判定) | ☐ |
| TC-P2-18 | 命中灵力增加 | 攻击命中敌人 | 玩家灵力条(SoulPower)增加,HUD 同步更新 | ☐ |
5.4 弹反系统
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P2-19 | 弹反触发 | 弹反键(默认 Q)在敌人攻击命中前 parryWindow 秒内按下 |
弹反成功:敌人进入受击僵直(parriedStunDuration),玩家不扣血,ParryFlash VFX 播放 |
☐ |
| TC-P2-20 | 弹反窗口外按键 | 过早或过晚按弹反键 | 弹反失败,玩家正常受击,无 ParryFlash | ☐ |
| TC-P2-21 | 弹反计数事件 | 成功弹反后检查 Console | EVT_ParrySuccess 频道触发,Stats.ParryCount +1(用于 ParryCountCondition 成就) |
☐ |
| TC-P2-22 | 不可弹反攻击 | 敌人使用标记为 Unblockable(InteractionTag)的攻击时尝试弹反 |
弹反无效,玩家正常受击,无 ParryFlash | ☐ |
| TC-P2-23 | 弹反冷却 | 成功弹反后立即再次按弹反键 | 弹反冷却期间无效(parryCooldown),CD 期间 UI 弹反图标变灰(若实现) |
☐ |
5.5 护盾与霸体(Poise)
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P2-24 | ShieldComponent 护盾吸收 | 装备护盾护符后受到攻击 | 护盾先扣除伤害,护盾耗尽后 HP 才扣减;护盾恢复计时器启动 | ☐ |
| TC-P2-25 | 霸体(Poise)保护 | 重攻击(Break Level >= poise)触发 HurtState;普通攻击(低于 poise)不触发 |
霸体值足够时攻击动画不被打断,霸体耗尽后下次攻击触发 HurtState | ☐ |
| TC-P2-26 | 霸体恢复 | 玩家停止受击一段时间 | 霸体值按 poiseRecoveryRate 恢复至满值 |
☐ |
5.6 状态效果系统
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P2-27 | Poison 中毒效果 | 使敌人/玩家受到 Poison StatusEffect(通过调试工具或专用敌人) | 每 tickInterval 秒扣除 tickDamage 血量,持续 duration 秒后自动移除,VFX 粒子(绿色)在角色上显示 |
☐ |
| TC-P2-28 | Burn 燃烧效果 | 触发 Burn | 类似 Poison,VFX 为橙红色,效果叠加计算(若实现 stack) | ☐ |
| TC-P2-29 | Stagger 硬直效果 | 触发 Stagger | 目标进入硬直动画,staggerDuration 秒内无法行动 |
☐ |
| TC-P2-30 | 状态效果叠加 | 同时触发 Poison + Burn | 两个效果独立计时,互不覆盖(StatusEffectManager 分别管理) | ☐ |
| TC-P2-31 | 状态效果免疫 | 对标记为免疫(DamageFlags 或 StatusResistance)的目标施加效果 | 效果不附着,Console 无报错 | ☐ |
5.7 VFX 与 Feedback 扩展
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P2-32 | HitFX 分类型播放 | 不同 HitFxType 攻击命中(斩击/钝击/魔法) | VFXCatalogSO.TryGetHitFX 正确查表,对应 VFX Prefab 从对象池生成,无 Debug.Assert 失败 |
☐ |
| TC-P2-33 | HurtFlash 受击闪白 | 玩家受击 | HurtFlash 动画播放,WaitForSeconds 使用缓存无 GC(Profiler 确认) |
☐ |
| TC-P2-34 | ParryFlash VFX | 弹反成功 | ParryFlash 粒子从对象池生成后自动归还(PooledObject.ReturnToPool) |
☐ |
| TC-P2-35 | FormSwitch VFX | 切换形态 | 形态切换 VFX(颜色渐变或粒子)播放,MMF_Player 事件触发 |
☐ |
| TC-P2-36 | Feel MMF_Player 反馈链 | 攻击/受击/弹反等事件触发 | PlayerFeedback.cs 各方法(PlayAttack/PlayHurt/PlayParry)正确触发对应 MMF_Player,无反射调用 |
☐ |
5.8 音频 Mixer 快照
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P2-37 | 战斗快照切换 | 玩家进入敌人 Alert 范围 | AudioMixer 渐变到战斗快照(鼓点增强,环境音淡出),过渡时长符合配置 | ☐ |
| TC-P2-38 | 平静快照恢复 | 击败所有敌人或离开战斗区 | AudioMixer 渐变回平静快照 | ☐ |
| TC-P2-39 | 形态 BGM 切换 | 切换形态 | BGM 切换到对应形态音轨,旧轨道淡出(双 AudioSource 交叉淡入) | ☐ |
5.9 难度系统
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P2-40 | 难度切换数值注入 | 在 SettingsPanel 切换难度(Easy/Normal/Hard) | DifficultyManager.ApplyDifficulty() 调用,EnemyStats 的伤害/HP 乘数按 DifficultyScalerSO 更新,PlayerStats 受伤倍率更新 |
☐ |
| TC-P2-41 | 难度数值持久化 | 切换 Hard → 存档 → 重载 | 重载后难度仍为 Hard,乘数正确应用 | ☐ |
5.10 敌人扩展(远程 / 飞行 / Boss 骨架)
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P2-42 | RangedEnemy 远程攻击 | 玩家进入 RangedEnemy 视野 | 敌人在保持距离状态下发射弹射物(从对象池生成),弹射物命中玩家扣血 | ☐ |
| TC-P2-43 | FlyingEnemy 飞行巡逻 | FlyingEnemy 在场景中 | 不受地形约束飞行巡逻,BatchLOSSystem 检测到玩家后追击,IsPlayerVisible 正确更新 |
☐ |
| TC-P2-44 | BossBase 血量分段 | BossBase 实例的 HP 降至配置阈值(如 50%) | BossBase.EnterPhase(1) 被调用,EVT_BossPhaseChanged 频道广播,Boss 进入第二阶段行为 |
☐ |
| TC-P2-45 | LootTableSO 掉落 | 击败有 LootTableSO 的敌人 | 按权重随机生成对应战利品(Geo / 道具),无 NullReferenceException |
☐ |
6. P3 世界与进程系统
6.1 房间切换与场景管理
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P3-01 | 自动触发传送点 | 玩家走入 _autoTrigger = true 的 RoomTransition 碰撞体 |
场景切换启动:广播 SceneLoadRequest,旧场景卸载,新场景加载,玩家在 EntryTransitionId 对应 PlayerSpawnPoint 出现 |
☐ |
| TC-P3-02 | 交互键触发传送点 | 玩家走入 _autoTrigger = false 的传送点,按交互键 |
弹出交互提示(InteractableDetector 管理),按键后触发场景切换 | ☐ |
| TC-P3-03 | 钥匙物品传送门 | 传送点设有 requiredItemId,玩家未持有时尝试进入 |
传送不触发,提示提示信息(如"需要 xx 钥匙") | ☐ |
| TC-P3-04 | Loading Screen | 场景切换时 ShowLoadingScreen = true 的传送请求 |
Loading 画面出现并在新场景加载完成后淡出 | ☐ |
| TC-P3-05 | 多场景 Persistent 常驻 | 场景切换全程 | Persistent 场景全程不卸载,ServiceLocator 中注册的服务始终有效 | ☐ |
| TC-P3-06 | 玩家位置记录(BreadcrumbTracker) | 玩家移动 30 秒 | BreadcrumbTracker.GetRecentCrumbs(5) 返回正确的近 5 个坐标,移动距离未超过阈值的位置不记录 |
☐ |
6.2 世界互动机关
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P3-07 | HazardZone 伤害 | 玩家进入 HazardZone 碰撞体 | 每 _damageInterval 秒扣除 _damage HP,离开后停止 |
☐ |
| TC-P3-08 | Collectible Geo 拾取 | 玩家接触 Geo 收集物 | Geo 数量增加,收集物弹起后被自动吸附(若实现磁吸),_collected 标记防止重复拾取 |
☐ |
| TC-P3-09 | DestructibleTile 破坏 | 玩家攻击 DestructibleTile | 根据 breakLevel vs 攻击 BreakLevel 判断:满足时瓦片碎裂(替换 Tilemap 或 Destroy),不满足时无效 |
☐ |
| TC-P3-10 | MovingPlatform 乘客跟随 | 玩家站上移动平台 | 玩家随平台移动,物理稳定无抖动;离开平台后父节点正确还原 | ☐ |
| TC-P3-11 | CrumblePlatform 崩塌 | 玩家站立在 CrumblePlatform 上 | 延迟 _crumbleDelay 秒后平台开始崩裂,_respawnDelay 秒后复原 |
☐ |
| TC-P3-12 | DirectionalInteractable 单向 | 从正确方向触发 DirectionalInteractable(攻击/接触/按键) | 机关激活,VoidEventChannel 广播;从错误方向触发无响应 | ☐ |
| TC-P3-13 | PhantomInteractable 太虚斩通过 | 玩家在 ShadowDecoy(太虚斩)形态下触碰 PhantomInteractable | 机关激活(PhantomBody Layer 检测有效);普通形态触碰无效 | ☐ |
| TC-P3-14 | DeathShade Geo 回收 | 死亡后重生,找到死亡遗骸(DeathShade)并交互 | Geo 增加(_onGeoRecovered.Raise(geo)),DeathShade 销毁,EVT_ShadeCollected 触发 |
☐ |
| TC-P3-15 | InteractableDetector 最近物体 | 同时有多个可交互物在范围内 | 始终与最近的可交互物交互,Gizmo 半径圈在编辑器下正确显示 | ☐ |
6.3 WorldStateRegistry 持久化
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P3-16 | 一次性机关状态保存 | 触发 _isOneShot = true 的 DirectionalInteractable → 存档 → 重载场景 |
机关已激活状态保留,WorldStateRegistry.IsFlagSet(id) 返回 true |
☐ |
| TC-P3-17 | 跨场景状态不丢失 | 触发机关 → 切换到另一个场景 → 返回 | 机关状态保持已激活(无重置) | ☐ |
6.4 液态谜题系统
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P3-18 | SwimState 游泳 | 玩家进入 LiquidZone 碰撞体 | 切换到 SwimState,浮力应用,游泳动画播放,潜水键可下潜,离开液体恢复原状态 | ☐ |
| TC-P3-19 | LiquidPuzzleController 谜题完成 | 操控 Valve/Pump/Drain 三件套达到谜题完成条件 | LiquidPuzzleController.IsSolved 变为 true,广播相关事件,机关门打开 |
☐ |
| TC-P3-20 | LiquidFlowSimulator 流向模拟 | 打开 Valve | 液体按重力/管道方向模拟流动(骨架级别验证:液位高度变化即可) | ☐ |
6.5 能力解锁与能力门禁
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P3-21 | AbilityUnlock 解锁演出 | 玩家进入 AbilityUnlock 触发区 | MMF_Player 反馈播放(无反射调用),等待 _cutsceneDuration 后调用 PlayerStats.UnlockAbility(),EVT_AbilityUnlocked 广播,组件销毁 |
☐ |
| TC-P3-22 | AbilityGate 阻挡 | 未解锁对应能力时走向 AbilityGate | 玩家无法通过(碰撞体激活),UI 提示"需要 xx 能力" | ☐ |
| TC-P3-23 | AbilityGate 实时开启 | 解锁能力后,已存在的 AbilityGate 响应 | 订阅 AbilityTypeEventChannelSO 的 AbilityGate 自动开启碰撞体,玩家可通过 |
☐ |
| TC-P3-24 | 能力持久化 | 解锁冲刺能力 → 存档 → 重载 | 重载后 PlayerStats.HasAbility(AbilityType.Dash) 仍为 true |
☐ |
6.6 护符与装备系统
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P3-25 | 护符装备生效 | 打开 InventoryPanel,将某 CharmSO 拖入装备槽 | EquipmentManager 调用 ICharmEffect.OnEquip(player),效果立即应用(如 HP+1、冲刺延长) |
☐ |
| TC-P3-26 | 护符卸除回滚 | 卸除已装备的护符 | ICharmEffect.OnUnequip(player) 回滚数值,效果消失 |
☐ |
| TC-P3-27 | 护符插槽限制 | 装备超过 maxCharmSlots 个护符 |
超出时提示"插槽不足",无法装备 | ☐ |
| TC-P3-28 | 护符持久化 | 装备护符 → 存档 → 重载 | 重载后护符仍处于装备状态,效果生效 | ☐ |
6.7 技能管理器与修改器
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P3-29 | 技能施放基础 | 形态切换到 Sky,按 SoulSkill 键 | 执行 FormSkillSO.effectType 对应逻辑(如 MeleeAoE 触发范围攻击),消耗 baseCost 灵力,进入 cooldown |
☐ |
| TC-P3-30 | 技能冷却 | 施放后立即再按技能键 | 冷却中无法施放,CD 结束后可再次施放 | ☐ |
| TC-P3-31 | SkillModifierRegistry 数值修改 | 装备影响某技能 Damage 的护符 | SkillModifierRegistry.GetEffectiveParams() 返回 damageMult > 1.0f,实际伤害增加 |
☐ |
| TC-P3-32 | SkillSlotOverride 技能替换 | 装备包含 SkillSlotOverride 的护符 |
指定形态/插槽的技能被替换为 replacementSkill,HUD 显示新技能图标 |
☐ |
6.8 任务系统
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P3-33 | 任务接取 | 与 QuestGiver NPC 交互,选择接受任务 | QuestManager.StartQuest(questSO) 调用,任务出现在 Journal UI |
☐ |
| TC-P3-34 | 任务目标追踪 | 完成任务中"击败 N 个敌人"目标 | QuestObjectiveSO.OnEnemyDefeated 计数更新,HUD 追踪数字变化 |
☐ |
| TC-P3-35 | 任务完成与奖励 | 满足所有目标后返回 QuestGiver | QuestManager.CompleteQuest(id) 调用,IRewardTarget.GiveReward() 执行(Geo/物品/能力奖励),任务状态变 Completed |
☐ |
| TC-P3-36 | 任务持久化 | 接取任务 → 完成部分目标 → 存档 → 重载 | 任务进度正确恢复(ObjectiveProgress 保存) | ☐ |
6.9 挑战房间
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P3-37 | 挑战房间触发 | 玩家进入 ChallengeRoomTrigger | 房间封锁(出口门关闭),ChallengeRoomManager.StartChallenge(so) 调用,限时计时器启动 |
☐ |
| TC-P3-38 | 挑战胜利 | 在时限内满足 ChallengeRoomSO 通关条件 |
出口门开启,奖励生成,EVT_ChallengeCompleted 广播 |
☐ |
| TC-P3-39 | 挑战失败 | 超时或玩家死亡 | 挑战失败流程触发,可重置 | ☐ |
6.10 地图模块
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P3-40 | 房间探索记录 | 进入新房间 | SaveData.Map.ExploredRooms 添加该房间 ID,迷雾(Fog of War)在 MapPanel 中对应区域揭开 |
☐ |
| TC-P3-41 | 传送点图标 | 存档点被激活后 | MapPanel 上对应位置显示传送点图标 | ☐ |
| TC-P3-42 | 地图面板开关 | 按地图键(默认 Tab) | MapPanel 开/关,全屏 Fog of War 渲染,已探索区域可见 | ☐ |
6.11 商店系统
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P3-43 | 商店面板打开 | 与 ShopKeeper NPC 交互 | ShopPanel 打开,显示 ShopInventorySO 中的商品列表及价格 |
☐ |
| TC-P3-44 | 购买道具 | 选择商品点击购买,Geo 足够 | Geo 扣减,道具加入背包,SaveData 同步更新 |
☐ |
| TC-P3-45 | Geo 不足拒绝 | 选择商品点击购买,Geo 不足 | 购买失败,提示"Geo 不足",无扣减 | ☐ |
7. P4 内容与完善
7.1 Boss 技能系统
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P4-01 | BossSkillExecutor 技能执行 | Boss 行为树调用 BossSkillExecutor.ExecuteSkill(so) |
技能协程启动,IsExecuting = true,攻击图案按 AttackPatternSO 时序逐步激活 HitBox |
☐ |
| TC-P4-02 | 技能中断 | 技能执行中切换阶段触发 InterruptCurrentSkill() |
StopCoroutine 被调用,IsExecuting 重置为 false,无挂起协程 |
☐ |
| TC-P4-03 | WFS 缓存零 GC | BossSkillExecutor 协程执行(Profiler 录制) | Profiler → GC Alloc 在协程帧无新 WaitForSeconds 分配,静态缓存生效 |
☐ |
| TC-P4-04 | 弱点窗口开启 | VulnerabilityWindow 触发条件满足(如弹反成功) |
WeakPointSystem.SetActive(true, multiplier) 调用,EVT_VulnerabilityWindowOpened 广播,弱点 HurtBox 可受击(伤害乘数生效) |
☐ |
| TC-P4-05 | TelegraphSystem 预警 VFX | BD_TelegraphAttack Task 执行 | 预警 VFX 从对象池生成,持续 _duration 秒后自动归还(PooledObject.ReturnToPool) |
☐ |
| TC-P4-06 | BD_EnterPhase 阶段切换 | BD 行为树执行 BD_EnterPhase Task | BossBase.EnterPhase(phaseIndex) 调用,EVT_BossPhaseChanged 广播,Boss 进入新阶段行为 |
☐ |
| TC-P4-07 | SkillSequenceSO 连段 | Boss 执行含 SkillSequenceSO 的技能 | SequenceStep[] 按 delayBeforeStep 间隔依次执行,RepeatIfPlayerInRange 逻辑生效 |
☐ |
| TC-P4-08 | BossResourceConfigSO 满值触发 | Boss 愤怒值积累到 maxValue |
autoTriggerOnFull = true 时自动执行 fullTriggerSkill,触发后 resetValueAfterTrigger 重置资源值 |
☐ |
7.2 对话与叙事模块
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P4-09 | 对话启动 | 与 InteractableNPC 交互 | DialoguePanel 开启,打字机效果逐字显示文本,InputReaderSO.EnableUIInput() 自动切换 |
☐ |
| TC-P4-10 | 对话快进 | 对话中按确认键 | 当前对话行完整显示(跳过打字机),再按则跳到下一行 | ☐ |
| TC-P4-11 | 分支选择 | 对话出现选项节点 | 选项 UI 列表显示,导航键选择,确认后走对应分支 | ☐ |
| TC-P4-12 | 对话结束恢复 | 对话播完最后一行 | DialoguePanel 关闭,InputReaderSO.EnableGameplayInput() 恢复游戏输入 |
☐ |
| TC-P4-13 | NPC 任务绑定 | QuestGiver NPC 对话结束触发任务 | QuestGiver.TryTriggerQuest() 调用,任务接取(见 TC-P3-33) |
☐ |
7.3 事件链与过场
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P4-14 | EventChain 顺序执行 | 触发 EventChainSO | 链条中各步骤按序执行(延迟/对话/VFX/音效),最后一步完成后 OnChainCompleted 回调 |
☐ |
| TC-P4-15 | CutsceneManager Timeline | 触发过场 | Unity Timeline 播放,玩家输入锁定,过场结束后输入恢复 | ☐ |
7.4 UI 完整面板
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P4-16 | PausePanel 暂停 | 按 Esc | 游戏暂停(Time.timeScale = 0),PausePanel 显示,继续/存档/退出按钮可用 |
☐ |
| TC-P4-17 | InventoryPanel 背包 | 打开背包 | 已持有护符/工具列表显示,装备/卸除操作生效(见 TC-P3-25/26) | ☐ |
| TC-P4-18 | SettingsPanel 设置 | 打开设置 | 音量/分辨率/按键重绑定选项显示,修改后实时生效 | ☐ |
| TC-P4-19 | AchievementPanel 成就 | 打开成就面板 | 已解锁成就高亮,未解锁为灰,进度条正确(如护符收集比例) | ☐ |
7.5 按键重绑定
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P4-20 | 重绑定操作 | 打开 SettingsPanel → 按键重绑定 → 点击攻击键 → 按新键 | 新键绑定生效,旧键不再触发攻击,绑定信息写入 PlayerPrefs | ☐ |
| TC-P4-21 | 绑定冲突检测 | 尝试将攻击键绑定为已被跳跃键占用的按键 | 提示冲突(或自动交换),不出现双动作绑定同一键 | ☐ |
| TC-P4-22 | 重置默认绑定 | 点击"恢复默认"按钮 | 所有绑定恢复出厂设置 | ☐ |
7.6 本地化系统
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P4-23 | 语言切换 | 在 SettingsPanel 切换语言(简体中文/English) | 所有 LocalizedText 组件立即更新为目标语言,无"Missing Key"占位符 |
☐ |
| TC-P4-24 | 语言持久化 | 切换语言 → 退出 Play Mode → 再次 Enter | 语言设置保留 | ☐ |
7.7 成就系统
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P4-25 | NailClashCountCondition | 触发 5 次 NailClash 弹反碰撞 | Stats.SkillUseCounts["NailClash"] >= 5,成就解锁,EVT_AchievementUnlocked 广播 |
☐ |
| TC-P4-26 | MapExplorationCondition | 探索达到 requiredRoomCount 个房间 |
成就解锁,AchievementPanel 对应项高亮 | ☐ |
| TC-P4-27 | UnlockedAllAbilitiesCondition | 解锁 requiredAbilities 中所有能力 |
位掩码检查通过,成就解锁 | ☐ |
| TC-P4-28 | 成就进度显示 | 部分完成 CollectedAllCharmsCondition | GetProgress() 返回 owned / totalCharmsCount,AchievementPanel 进度条正确 |
☐ |
7.8 平台支撑(Steam / 存档云同步)
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P4-29 | PlatformBootstrap 初始化 | Play Mode(非编辑器模式或 Dev Build) | Steam SDK 初始化(Console 无 Steamworks.NET 错误),不崩溃 |
☐ |
| TC-P4-30 | Steam 成就上报 | 满足成就条件后 | SteamUserStats.SetAchievement() 被调用(通过 Steam SDK 日志验证);Steamworks 未初始化时本地静默降级 |
☐ |
7.9 支撑模块(调试 / 无卡点 / 无障碍 / 速通)
| TC-ID | 测试项 | 操作步骤 | 期望结果 | ☐ |
|---|---|---|---|---|
| TC-P4-31 | DebugCheatSystem 作弊 | Development Build / Editor:输入作弊码(如全体 HP 回满) | 作弊生效,Console 输出 [Cheat] HP restored;Release Build 中指令无效 |
☐ |
| TC-P4-32 | AntiSoftlockSystem 出门触发 | 玩家在封闭区域卡住超过 stuckTimeout |
AntiSoftlock 弹出选项("是否返回最近存档点"),选是则安全返回 | ☐ |
| TC-P4-33 | AccessibilityManager 色盲模式 | 设置开启 Color Blind 模式 | PaletteSwapSystem 切换色盲调色板,VFX 颜色对比度提升 |
☐ |
| TC-P4-34 | AccessibilityManager 震动开关 | 关闭震动 | NiceVibrations 调用不触发(MMVibrationManager 在 disabled 时静默) |
☐ |
| TC-P4-35 | SpeedrunTimer IGT 计时 | Play Mode 进入游戏 | SpeedrunTimer 从 0 开始计时,暂停时停止(IGT 不含暂停),存档保存 ElapsedTime |
☐ |
| TC-P4-36 | AnalyticsManager 本地日志 | 触发若干游戏事件(死亡/存档/能力解锁) | Analytics/session_{date}.jsonl 文件在磁盘生成,包含对应事件条目 |
☐ |
8. 全流程端到端验证
以下场景模拟完整游戏会话,覆盖跨系统协同:
E2E-01:新游戏完整启动流程
步骤:
- 删除所有存档文件(
Application.persistentDataPath/saves/) - Enter Play Mode,进入主菜单
- 选择"新游戏",确认选择难度
- 场景加载完成,玩家出现在起始房间
- 观察 Console 和 Profiler
期望结果:
- 无 Error,Persistent 场景 + 游戏场景同时加载
- ServiceLocator 注册日志正确(7 个核心服务全部注册)
- HUD 正确初始化(HP 满,Geo=0,形态 = Sky)
- 输入立即响应
- GC Alloc 在启动后 3 秒内趋近 0(Profiler 确认)
E2E-02:完整战斗至死亡复活流
步骤:
- 与 SavePoint 交互存档
- 进入带 LootTableSO 的普通敌人房间
- 使用 3 段连击击败敌人
- 拾取掉落 Geo
- 进入第二波(含远程敌人),故意让玩家死亡
- 死亡屏幕出现,等待复活
期望结果:
- 连击判定正确(HitBox 时序准确,无穿透)
- Geo 正确累加(HUD 同步)
- 远程敌人弹射物从对象池生成,无
Instantiate调用(Profiler 对象池) - 死亡:DeadState 冻结物理,
EVT_PlayerDied广播 - DeathShade 在死亡位置生成,含本次积累的 Geo
- 复活在上次存档点,HP 满,Geo = 0(未回收 DeathShade 则 Geo 不恢复)
E2E-03:多房间探索 + 传送 + 存档完整性
步骤:
- 起始房间探索,地图揭开
- 通过 RoomTransition 进入第二房间(带 Loading Screen)
- 第二房间激活 AbilityGate → 发现需要冲刺能力
- 找到 AbilityUnlock 触发区,解锁冲刺
- AbilityGate 自动开启,通过
- 与 SavePoint 交互存档
- Exit Play Mode → Enter Play Mode → 加载存档
期望结果:
- 每步无 Error
- 地图探索记录(
ExploredRooms)在两个房间均有记录 - 冲刺能力解锁后 AbilityGate 实时响应(无需重进场景)
- 存档重载后:位置=SavePoint 坐标,冲刺能力=已解锁,地图探索=保留,Geo=已保存值
E2E-04:Boss 完整战斗流
步骤:
- 进入 Boss 房间,触发 Boss Arena 锁定
- 观察 Boss 第一阶段行为树(巡逻→预警→攻击→技能连段)
- HP 降至 50%,Boss 进入第二阶段
- 成功弹反 Boss 攻击,触发弱点窗口
- 对弱点集中攻击
- Boss HP 归零,死亡
期望结果:
- BD_IsPlayerVisible 读取 BatchLOSSystem 缓存(无每帧 Raycast)
- 阶段切换:
EVT_BossPhaseChanged广播,UI Boss HP 条颜色变化 - 弹反成功:弱点 HurtBox 激活,伤害乘数生效,
EVT_VulnerabilityWindowOpened广播 - TelegraphSystem VFX 从对象池生成归还,无残留
- Boss 死亡:
EVT_BossFightEnded广播,Arena 解锁,战利品生成
E2E-05:成就全流程
步骤:
- 累计触发 5 次 NailClash(弹反碰撞检测)
- 探索
requiredRoomCount个房间 - 打开 AchievementPanel
期望结果:
- NailClash 计数通过
SaveData.Stats.SkillUseCounts["NailClash"]存档 - 房间探索通过
SaveData.Map.ExploredRooms存档 - AchievementPanel 对应成就解锁高亮,进度条准确
- Steam 成就上报(若在 Dev Build 模式)
9. 验收通过标准
必须全部通过(阻断级)
- ENV-01~07 全通过(0 编译错误)
- TC-P0-01 ~ TC-P0-05(基础设施可运行)
- TC-P1-01 ~ TC-P1-08(最小可玩流程)
- E2E-01(新游戏启动无 Error)
- E2E-02(战斗至死亡复活完整流程)
核心功能通过(发布前必须通过)
- P2 系列:TC-P2-01 ~ TC-P2-45(核心玩法全覆盖)
- P3 系列:TC-P3-01 ~ TC-P3-45(世界互动全覆盖)
- E2E-03(多房间探索存档完整性)
- E2E-04(Boss 完整战斗流)
支撑功能通过(发布质量)
- P4 系列:TC-P4-01 ~ TC-P4-36(内容与完善全覆盖)
- E2E-05(成就全流程)
性能基准(Profile 验证)
| 指标 | 基准值 | 验证方法 |
|---|---|---|
| 战斗帧率(单房间 + 3 敌人) | ≥ 60 FPS(Mobile:≥ 30) | Profiler CPU Usage |
| 战斗中帧 GC Alloc | ≤ 0 B/帧(稳定运行后) | Profiler GC Alloc Track |
| 内存增量(10 分钟游戏) | ≤ 5 MB(对象池正常回收) | Profiler Memory Profiler |
| 场景加载时间(带 Loading Screen) | ≤ 2 秒(含 Addressables 异步) | Stopwatch / SceneLoader 日志 |
10. 缺陷登记表
测试过程中发现的缺陷记录于此,格式与代码评审 TD 编号体系对齐(使用 BUG- 前缀区分)。
| BUG-ID | 严重程度 | 发现于 | 复现 TC | 描述 | 状态 | 修复版本 |
|---|---|---|---|---|---|---|
| (示例) BUG-01 | 高 | E2E-02 | TC-P2-17 | HitBox 在 Attack3 后未 Deactivate,造成持续判定 | ⏳ 待修复 | — |
文档维护:每次 Phase 验收后更新「阶段验收状态总览」及「缺陷登记表」;新增测试用例按模块追加,TC-ID 自增。