fix(enemy): Pace 巡逻改边沿触发翻向,修边缘左右抖动

TickPatrol 跑在 Update(可变帧率),IsWallAhead/IsLedgeAhead 在 FixedUpdate
刷新。原电平触发(每帧 blocked 就翻向)会在检测刷新前的多个 Update 帧把同一
障碍连翻多次→掉头边缘左右抖动几次才正常。改为边沿触发(仅障碍首次出现时翻
一次),用 _paceBlockedPrev 记录上帧状态。PlayMode 验证:踱步移动正常、无
连续快速翻转。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@
This commit is contained in:
2026-07-10 14:36:53 +08:00
parent 6a34b42db0
commit 6f52e4ff81
@@ -26,6 +26,7 @@ namespace BaseGames.Enemies
private LocomotionMode _gaitMode; private LocomotionMode _gaitMode;
private bool _gaitInit; private bool _gaitInit;
private float _paceDir = 1f; private float _paceDir = 1f;
private bool _paceBlockedPrev;
private int _wpIndex = -1; private int _wpIndex = -1;
private int _wpDir = 1; private int _wpDir = 1;
private bool _warnedNoWaypoints; private bool _warnedNoWaypoints;
@@ -113,7 +114,12 @@ namespace BaseGames.Enemies
case PatrolStrategy.Pace: // 撞墙/悬崖翻向的来回踱步(速度驱动,不依赖 nav) case PatrolStrategy.Pace: // 撞墙/悬崖翻向的来回踱步(速度驱动,不依赖 nav)
var mv = _enemy.Movement; var mv = _enemy.Movement;
if (mv != null && (mv.IsWallAhead || mv.IsLedgeAhead)) _paceDir = -_paceDir; bool blocked = mv != null && (mv.IsWallAhead || mv.IsLedgeAhead);
// 边沿触发:仅在"障碍首次出现"时翻向一次。TickPatrol 跑在 Update(可变帧率)
// 而 IsWallAhead/IsLedgeAhead 在 FixedUpdate 刷新——若用电平触发(每帧 blocked 就翻),
// 检测刷新前的多个 Update 帧会把同一障碍连翻多次→边缘左右抖动。
if (blocked && !_paceBlockedPrev) _paceDir = -_paceDir;
_paceBlockedPrev = blocked;
_enemy.MoveInDirection(_paceDir); _enemy.MoveInDirection(_paceDir);
break; break;