docs(enemy): 脱困改用敌人自身步速(MoveHorizontal/WalkSpeed),移除独立速度参数

This commit is contained in:
2026-07-27 16:45:00 +08:00
parent e7f1633877
commit 579499e678
@@ -68,14 +68,30 @@
```csharp
// EnemyNavAgent 新增
[Header("脱图脱困(中心离开烘焙段时自动走回可行走地面)")]
[Tooltip("脱困时的水平移动速度(m/s)。脱图期间无法寻路,只能速度驱动走回地面。")]
[SerializeField] [Min(0f)] private float _offGraphRecoverySpeed = 2f;
[Tooltip("脱困持续超过此时长仍未回到导航图,输出一次告警(0 = 不告警)。")]
[SerializeField] [Min(0f)] private float _offGraphWarnAfter = 2f;
public bool IsOnNavGraph => _navAgent != null && _navAgent.HasValidPosition;
```
**脱困移动使用敌人自身的移动,不引入独立速度参数。** 巡逻层的方向驱动移动路径为:
```
EnemyLocomotion(Pace) _enemy.MoveInDirection(dir)
→ PendingInput.MoveDir = dir(不写 MoveSpeed
→ EnemyMovement.ConsumeInputMoveSpeed == 0 → MoveHorizontal(dir)
→ vel.x = dir * _config.WalkSpeed ← 敌人自己 EnemyStatsSO 配的步行速度
```
脱困沿用同一条路径:写 `PendingInput.MoveDir = dir`**显式置 `MoveSpeed = 0f`**`WantStop = false`
(等价于 `EnemyBase.MoveInDirection(dir)`),从而走 `MoveHorizontal` → 敌人自身 `WalkSpeed`
> ⚠ `MoveSpeed` 是**持久字段**(不逐帧清零),而 `EnemyNavAgent` 的段内移动会把它写成导航速度。
> 故脱困必须**显式清零** `MoveSpeed`,否则会沿用上一次的导航速度而非敌人自身步速。
附带好处:`MoveHorizontal` 自带 `WouldBlockAhead` 夹紧(墙 + 悬崖),
脱困走回平台时天然不会从另一侧冲出去。
`FixedUpdate` 流程(在现有逻辑之前),**判定顺序即为排除顺序**:
1. **`_navAgent.IsOnLink` → 立即跳过脱困**。⚠ 关键:PB2d 在穿越连接段时会主动把映射置为无效
`NavAgent.UpdateMappedPosition()` 开头 `if (IsOnLink) { currentMappedPosition = Invalid; return; }`),
@@ -83,7 +99,8 @@ public bool IsOnNavGraph => _navAgent != null && _navAgent.HasValidPosition;
2. `mapped = _navAgent.HasValidPosition`;映射正常 → 清脱困计时,走原有逻辑。
3. 未映射且 `!_enemyMovement.IsGrounded` → 处于空中(下落中),不干预(落地后自会重判)。
4. 未映射且着地 → `dir = _enemyMovement.GroundSideDir()`
- `dir != 0` → 写入 `PendingInput.MoveDir = dir; MoveSpeed = _offGraphRecoverySpeed;`**return**(跳过段推进/受阻处理)。
- `dir != 0` → 写入 `PendingInput.MoveDir = dir; MoveSpeed = 0f; WantStop = false;`(=敌人自身步速),
**return**(跳过段推进/受阻处理)。
- `dir == 0` **且两侧脚下都无地** → 异常几何 → 按 `_offGraphWarnAfter` 限频告警,暴露根因,不臆造恢复。
- `dir == 0` **但两侧都有地**(中心下方恰为窄缝等罕见几何)→ 不告警、不干预,交由物理与后续帧自然解决。
@@ -138,7 +155,8 @@ if (blocked && (!_paceBlockedPrev || oppositeFree)) { _paceDir = -_paceDir; ...
| 正在穿越 NavLink`IsOnLink`) | PB2d 本身即置映射无效,**必须最先排除**,否则每次跳/落都被脱困打断(见 §3.1 第 1 步) |
| 两侧脚下都无地 | 限频告警(含坐标),不臆造恢复——暴露关卡/物理异常 |
| 两侧脚下都有地 | 不告警、不干预(罕见几何,交由物理与后续帧自然解决) |
| 恢复速度配成 0 | 敌人不动 → 由 `_offGraphWarnAfter` 告警暴露不做隐式兜底 |
| `EnemyStatsSO.WalkSpeed` 配成 0 | 敌人无法脱困(也本就无法巡逻)→ 由 `_offGraphWarnAfter` 告警暴露不做隐式兜底 |
| 脱困期间需要先转身 | `MoveHorizontal``if (_isTurning) return;` 会让转身动画期间暂不位移,转身结束后自然继续——符合预期,无需特殊处理 |
| 飞行敌人 / 无导航敌人 | `IsOnNavGraph` 恒 true,本机制不介入 |
| 脱困期间玩家进入追逐区 | AI 照常切追击态;追击同样经 Nav,脱困先把敌人带回图上再寻路 |