diff --git a/Assets/_Game/Scripts/Enemies/Navigation/EnemyLocomotion.cs b/Assets/_Game/Scripts/Enemies/Navigation/EnemyLocomotion.cs index 0b7e4d30..aedaca57 100644 --- a/Assets/_Game/Scripts/Enemies/Navigation/EnemyLocomotion.cs +++ b/Assets/_Game/Scripts/Enemies/Navigation/EnemyLocomotion.cs @@ -194,16 +194,23 @@ namespace BaseGames.Enemies } break; } - // 仅首次或"已到达当前路点"时推进并寻路——不依赖 IsMoving - // (PathBerserker2d 寻路跨帧异步,IsMoving 在寻路计算期间为 false,会误触发每帧推进)。 // 到达判定对"吸附后的可达点"做,而非原始路点:原始路点可能摆在空中/崖外, // 与之的距离永远进不了到达半径 → 卡死;吸附点是身体站得住的可达点。 - if (_wpIndex < 0 || - Vector2.Distance(_enemy.transform.position, _wpResolvedGoal) <= _waypointArriveRadius) + bool wpArrived = _wpIndex >= 0 && + Vector2.Distance(_enemy.transform.position, _wpResolvedGoal) <= _waypointArriveRadius; + if (_wpIndex < 0 || wpArrived) { + // 首次 / 到达当前路点 → 推进到下一路点并寻路 AdvanceWaypoint(); SetWaypointGoal(); } + else if (_enemy.Nav != null && !_enemy.Nav.IsMoving) + { + // 有目标但 nav 空闲且未到达:初始寻路未成(如刚出生、尚未映射到导航图那一帧发的 MoveTo 失败) + // 或路径中途丢失 → 重发同一目标恢复。只重发、不推进索引;RequestMoveTo 自带 0.25s 防抖, + // 寻路跨帧计算期间的重发会被防抖吞掉,不会每帧重启寻路。 + _enemy.MoveTo(_wpResolvedGoal); + } break; } }