多轮审查和修复
This commit is contained in:
@@ -84,17 +84,102 @@
|
||||
|
||||
> HitBox / HurtBox 依赖 Layer 碰撞矩阵,未配置时攻击不触发伤害。
|
||||
|
||||
**步骤**:
|
||||
1. 菜单 `Edit → Project Settings → Physics 2D`
|
||||
2. 滚动到底部 **Layer Collision Matrix** 区域
|
||||
3. 确认以下组合已勾选(绿色):
|
||||
**详细配置步骤**:
|
||||
|
||||
| 行 Layer | 列 Layer | 说明 |
|
||||
1. 打开菜单 `Edit → Project Settings → Tags and Layers`
|
||||
2. 在 User Layer 中创建以下 Layer(名称必须完全一致,区分大小写):
|
||||
|
||||
| Layer 名称 | 用途 |
|
||||
|-----------|------|
|
||||
| `Player` | 玩家主物体(Rigidbody2D 所在) |
|
||||
| `Enemy` | 敌人主物体(Rigidbody2D/导航代理所在) |
|
||||
| `Ground` | 地面、墙体、平台等场景碰撞体 |
|
||||
| `PlayerHitBox` | 玩家攻击判定触发器 |
|
||||
| `PlayerHurtBox` | 玩家受击判定触发器 |
|
||||
| `EnemyHitBox` | 敌人攻击判定触发器 |
|
||||
| `EnemyHurtBox` | 敌人受击判定触发器 |
|
||||
| `TriggerZone` | 存档点、相机区、剧情触发区 |
|
||||
|
||||
3. 给对象分配 Layer(Scene 中逐个核对):
|
||||
|
||||
| 对象 | Layer |
|
||||
|------|-------|
|
||||
| Player 根节点(含 Rigidbody2D) | `Player` |
|
||||
| Player/HitBox 子节点 | `PlayerHitBox` |
|
||||
| Player/HurtBox 子节点 | `PlayerHurtBox` |
|
||||
| Enemy 根节点(含 Rigidbody2D 或 NavAgent) | `Enemy` |
|
||||
| Enemy/HitBox 子节点(如果有) | `EnemyHitBox` |
|
||||
| Enemy/HurtBox 子节点 | `EnemyHurtBox` |
|
||||
| Tilemap Ground、静态障碍 | `Ground` |
|
||||
| SavePoint、CameraTrigger、RoomTrigger | `TriggerZone` |
|
||||
|
||||
4. 打开菜单 `Edit → Project Settings → Physics 2D`
|
||||
5. 滚动到底部 `Layer Collision Matrix`
|
||||
6. 按 Unity `Layer Collision Matrix` 逐格设置(与你截图中的排列一致):
|
||||
|
||||
当前矩阵显示顺序(从上到下/从左到右)为:
|
||||
|
||||
| 序号 | Layer |
|
||||
|------|-------|
|
||||
| 0 | `Default` |
|
||||
| 1 | `TransparentFX` |
|
||||
| 2 | `Ignore Raycast` |
|
||||
| 3 | `Player` |
|
||||
| 4 | `Water` |
|
||||
| 5 | `UI` |
|
||||
| 6 | `Enemy` |
|
||||
| 7 | `Ground` |
|
||||
| 8 | `PlayerHitBox` |
|
||||
| 9 | `PlayerHurtBox` |
|
||||
| 10 | `EnemyHitBox` |
|
||||
| 11 | `EnemyHurtBox` |
|
||||
| 12 | `TriggerZone` |
|
||||
|
||||
在该排列下,只需要重点修改以下交叉格(其余保持默认即可):
|
||||
|
||||
| 行 Layer | 列 Layer | 设置 |
|
||||
|---------|---------|------|
|
||||
| `PlayerHitBox` | `EnemyHurtBox` | 玩家攻击打敌人 |
|
||||
| `EnemyHitBox` | `PlayerHurtBox` | 敌人攻击打玩家 |
|
||||
| `Player` | `Ground` | 玩家落地检测 |
|
||||
| `Enemy` | `Ground` | 敌人落地检测 |
|
||||
| `Player` | `Ground` | ✅ |
|
||||
| `Enemy` | `Ground` | ✅ |
|
||||
| `Player` | `Enemy` | ✅ |
|
||||
| `PlayerHitBox` | `EnemyHurtBox` | ✅ |
|
||||
| `EnemyHitBox` | `PlayerHurtBox` | ✅ |
|
||||
| `TriggerZone` | `Player` | ✅ |
|
||||
| `PlayerHitBox` | `Ground` | ❌ |
|
||||
| `EnemyHitBox` | `Ground` | ❌ |
|
||||
| `PlayerHurtBox` | `Ground` | ❌ |
|
||||
| `EnemyHurtBox` | `Ground` | ❌ |
|
||||
| `PlayerHitBox` | `PlayerHurtBox` | ❌ |
|
||||
| `EnemyHitBox` | `EnemyHurtBox` | ❌ |
|
||||
| `PlayerHitBox` | `Player` | ❌ |
|
||||
| `EnemyHitBox` | `Enemy` | ❌ |
|
||||
| `TriggerZone` | `Enemy` | ❌ |
|
||||
|
||||
定位技巧(与 Unity 面板一致):
|
||||
- Unity 只显示下三角矩阵,`A × B` 与 `B × A` 是同一个格
|
||||
- 找不到某一格时,优先在“行名较靠下”的那一行里找对应列
|
||||
- 先设置 5 个核心开启项:`Player-Ground`、`Enemy-Ground`、`PlayerHitBox-EnemyHurtBox`、`EnemyHitBox-PlayerHurtBox`、`TriggerZone-Player`
|
||||
|
||||
7. 组件级别补充设置(和矩阵一起生效):
|
||||
- HitBox 与 HurtBox 的 Collider2D 必须 `Is Trigger = true`
|
||||
- Player/Enemy 主体 Collider2D 必须 `Is Trigger = false`
|
||||
- 至少一方需要 Rigidbody2D 才会触发 Trigger 回调(本项目通常在主体根节点)
|
||||
|
||||
8. 快速验证:
|
||||
- 玩家攻击敌人:应触发 `EVT_HitConfirmed`
|
||||
- 敌人攻击玩家:玩家 HP 下降且 HUD 刷新
|
||||
- 玩家接触 SavePoint:应触发 `EVT_SavePointActivated`
|
||||
|
||||
### 1.6 本文统一测试场景与加载方式(必须按此执行)
|
||||
|
||||
为避免“服务层未加载”或“房间场景缺对象”的误判,本文所有验证默认使用以下场景组合:
|
||||
|
||||
1. 打开 `Assets/Scenes/Persistent.unity`
|
||||
2. 使用 Additive 方式再打开 `Assets/Scenes/TestRoom.unity`
|
||||
3. 在 Hierarchy 中确认 `Persistent` 与 `TestRoom` 两个场景同时处于已加载状态
|
||||
4. 若当前只开了 `TestRoom.unity`,请先停止测试并改为上述双场景组合后再执行
|
||||
|
||||
> 例外:仅测试单纯美术或单房间静态内容时可只开 `TestRoom.unity`。但凡涉及输入、服务注册、事件总线、存档、死亡复活,必须使用双场景组合。
|
||||
|
||||
---
|
||||
|
||||
@@ -148,7 +233,7 @@
|
||||
_deathScreenController → DeathScreenController GameObject 引用
|
||||
```
|
||||
|
||||
### 2.2 测试房间场景 —— `Assets/Scenes/Rooms/TestRoom.unity`
|
||||
### 2.2 测试房间场景 —— `Assets/Scenes/TestRoom.unity`
|
||||
|
||||
```
|
||||
[TestRoom]
|
||||
@@ -222,12 +307,21 @@
|
||||
|
||||
## 3. 编辑器扩展工具一览
|
||||
|
||||
Phase 0/1 实现了以下 Editor-only 工具,验证过程中会频繁用到:
|
||||
当前验证会用到两类入口:
|
||||
|
||||
1. **BaseGames 自定义菜单工具**:会出现在 `BaseGames` 菜单下
|
||||
2. **Unity / 第三方现成窗口**:仍然在各自原生菜单里,不会出现在 `BaseGames` 菜单下
|
||||
|
||||
| 工具 | 菜单路径 | 快捷键 | 用途 |
|
||||
|------|---------|--------|------|
|
||||
| **Event Bus Monitor** | `BaseGames → Tools → Event Bus Monitor` | `Ctrl+Shift+E` | Play 模式下实时查看所有 SO 事件触发记录 |
|
||||
| **Validate AddressKeys** | `Tools → Validate AddressKeys` | — | 手动校验 AddressKeys 常量与 Addressable 分组一致性 |
|
||||
| **Create Event Channel Assets** | `BaseGames → Tools → Create Event Channel Assets` | — | 一键生成全局事件频道资产 |
|
||||
| **Reimport Event Channel Assets** | `BaseGames → Tools → Reimport Event Channel Assets` | — | 批量重导入 `Assets/Data/Events` 下的事件资产 |
|
||||
| **Validate Address Keys** | `BaseGames → Tools → Validate Address Keys` | — | 手动校验 AddressKeys 常量与 Addressable 分组一致性 |
|
||||
| **Scaffold Persistent Scene** | `BaseGames → Tools → Scaffold Persistent Scene` | — | 一键生成 Persistent 场景基础层级与核心组件骨架 |
|
||||
| **Scaffold Test Room** | `BaseGames → Tools → Scaffold Test Room` | — | 一键生成 TestRoom 基础层级、Player/Enemy/Camera/SavePoint 骨架 |
|
||||
| **Apply Script Execution Order Preset** | `BaseGames → Tools → Apply Script Execution Order Preset` | — | 一键写入推荐的脚本执行顺序 |
|
||||
| **Validate Script Execution Order Preset** | `BaseGames → Tools → Validate Script Execution Order Preset` | — | 校验当前执行顺序是否符合推荐值 |
|
||||
| **Animancer Window** | `Window → Animation → Animancer` | — | 查看当前播放的动画状态和混合树 |
|
||||
| **Behavior Designer** | 选中敌人 → Inspector → Open | — | 实时观察 BT 节点执行路径 |
|
||||
| **Audio Mixer** | `Window → Audio → Audio Mixer` | — | 查看实时音频电平 |
|
||||
@@ -246,8 +340,10 @@ Phase 0/1 实现了以下 Editor-only 工具,验证过程中会频繁用到:
|
||||
|
||||
#### 步骤 1:确认执行顺序配置
|
||||
|
||||
1. 菜单 `Edit → Project Settings → Script Execution Order`
|
||||
2. 确认以下顺序存在(数字越小越先执行):
|
||||
1. 优先使用一键菜单:`BaseGames → Tools → Apply Script Execution Order Preset`
|
||||
2. (可选)执行校验菜单:`BaseGames → Tools → Validate Script Execution Order Preset`
|
||||
3. 若需人工复核,打开 `Edit → Project Settings → Script Execution Order`
|
||||
4. 确认以下顺序存在(数字越小越先执行):
|
||||
|
||||
| 脚本 | ExecutionOrder |
|
||||
|------|---------------|
|
||||
@@ -260,7 +356,7 @@ Phase 0/1 实现了以下 Editor-only 工具,验证过程中会频繁用到:
|
||||
|
||||
#### 步骤 2:Play 模式验证
|
||||
|
||||
1. 打开包含 `Persistent.unity` 的场景
|
||||
1. 按 [1.6 本文统一测试场景与加载方式](#16-本文统一测试场景与加载方式必须按此执行) 加载 `Persistent.unity + TestRoom.unity`
|
||||
2. 按 **Play**
|
||||
3. 查看 Console,预期输出(顺序):
|
||||
```
|
||||
@@ -381,7 +477,21 @@ ISceneService: SceneService
|
||||
|
||||
**验证目标**:物理按键正确映射到 InputReaderSO 事件,InputBuffer 缓冲窗口生效。
|
||||
|
||||
#### 步骤 1:Inspector 字段核查
|
||||
#### 步骤 0:先进入正确场景(必做)
|
||||
|
||||
1. 按 [1.6 本文统一测试场景与加载方式](#16-本文统一测试场景与加载方式必须按此执行) 加载场景
|
||||
2. 打开 `BaseGames → Tools → Event Bus Monitor`
|
||||
3. 在 EventBusMonitorWindow 点击 **Clear** 清空历史记录
|
||||
4. 在 Filter 输入框输入 `Pause`
|
||||
|
||||
#### 步骤 1:InputReader 挂载与引用核查
|
||||
|
||||
1. 在 `Persistent` 场景中选中 `InputReaderHolder`
|
||||
2. 检查 `InputReaderBootstrap._inputReader`:必须已拖拽 `Assets/Data/Input/InputReader.asset`
|
||||
3. 检查 `InputReader.asset`(ScriptableObject)中的 `_inputActions`:必须指向 `Assets/Settings/PlayerInputActions.inputactions`
|
||||
4. 检查 `_onPauseRequested`:必须指向 `Assets/Data/Events/EVT_PauseRequested.asset`
|
||||
|
||||
#### 步骤 2:Inspector 字段核查
|
||||
|
||||
选中 `InputBuffer` 组件(挂在 Player 上):
|
||||
|
||||
@@ -392,18 +502,40 @@ ISceneService: SceneService
|
||||
| `_attackBufferDuration` | **0.12** |
|
||||
| `_dashBufferDuration` | **0.10** |
|
||||
|
||||
#### 步骤 2:InputActions 配置验证
|
||||
#### 步骤 3:InputActions 配置验证
|
||||
|
||||
1. 双击 `Assets/Settings/PlayerInputActions.inputactions` 打开 Input System 编辑器
|
||||
2. 确认以下 **Action Maps** 存在:
|
||||
- `Gameplay`(含 Move / Jump / Attack / Dash / Parry 等 Actions)
|
||||
- `UI`(含 Navigate / Submit / Cancel 等)
|
||||
- `Cutscene`(含 Skip 等)
|
||||
3. 检查 `Jump` Action 的 Binding:
|
||||
- `Gameplay`(含 Move / Jump / Attack / DownAttack / UpAttack / Parry / Dash / UseSpring / Switch* / SoulSkill / SpiritSkill* / Interact / Pause)
|
||||
- `UI`(含 Navigate / Submit / Cancel / Pause / Point)
|
||||
3. 检查 `Pause` Action 的 Binding(Gameplay 与 UI 均需存在):
|
||||
- `Keyboard` → `Escape`
|
||||
- `Gamepad` → `Start`
|
||||
4. 检查 `Jump` Action 的 Binding:
|
||||
- `Keyboard` → `Space`
|
||||
- `Gamepad` → `Button South`(南键)
|
||||
|
||||
#### 步骤 3:缓冲窗口验证(跳跃缓冲)
|
||||
#### 步骤 4:Escape 事件链验证(本阶段主验证项)
|
||||
|
||||
1. 按 **Play**
|
||||
2. 按一次 `Escape`
|
||||
3. 观察 Console,必须出现一次链路日志:
|
||||
|
||||
```
|
||||
[InputReaderSO.HandlePause] PAUSE INPUT DETECTED!
|
||||
[InputReaderSO.HandlePause] Invoking PauseEvent...
|
||||
[InputReaderSO.HandlePause] Raising _onPauseRequested channel...
|
||||
```
|
||||
|
||||
4. 观察 EventBusMonitorWindow(Filter=Pause):
|
||||
- 应新增 1 条 `EVT_PauseRequested`
|
||||
- `Subs` 应大于 0(通常为 2)
|
||||
5. 再按一次 `Escape`
|
||||
6. 再次确认仅新增 1 条 `EVT_PauseRequested`
|
||||
|
||||
> 通过标准:按 2 次 Escape,新增 2 条 `EVT_PauseRequested`。若出现 4 条,表示重复绑定回归,需要排查 InputReaderSO 的重复 Bind。
|
||||
|
||||
#### 步骤 5:缓冲窗口验证(跳跃缓冲)
|
||||
|
||||
1. 让玩家跳跃到空中
|
||||
2. **在落地前约 100–150ms**(目测约 3–5 帧前)按下跳跃键
|
||||
|
||||
Reference in New Issue
Block a user