feat(enemy): 目标点吸附统一处理导航宽度,Waypoint 不再卡崖边
将"角色导航宽度"收口到导航执行层单一入口,意图层(Locomotion/AI)只递原始目标、不再感知身体尺寸: - NavAgent 新增 TryGetStandablePointNear:把世界点映射到最近可行走段并按 endMargin 内缩两端(与 SetRandomDestinationOnCurrentSegment 同源) - EnemyNavAgent 新增 ResolveStandablePoint,以 EnemyMovement.EdgeSafeMargin(半宽+落崖余量)为唯一宽度真源;加 _goalMapSearchRadius - IPathAgent 暴露 ResolveStandablePoint;FlyingDirectNavigator 原样返回(飞行无崖沿约束),NullPathAgent 空实现 - EnemyLocomotion Waypoint 分支改用吸附后的可达点做移动与到达判定,修复路点摆在空中/崖外时永不到达而卡死;吸附失败显式报错暴露误配,不静默兜底 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -38,6 +38,8 @@ namespace BaseGames.Enemies
|
||||
private int _wpIndex = -1;
|
||||
private int _wpDir = 1;
|
||||
private bool _warnedNoWaypoints;
|
||||
// 当前路点吸附后的"站得住"目标(宽度由 Nav 层解析,本层不感知身体尺寸)
|
||||
private Vector2 _wpResolvedGoal;
|
||||
// Wander 到点停顿状态
|
||||
private bool _wanderPausing;
|
||||
private float _wanderPauseTimer;
|
||||
@@ -193,16 +195,34 @@ namespace BaseGames.Enemies
|
||||
}
|
||||
// 仅首次或"已到达当前路点"时推进并寻路——不依赖 IsMoving
|
||||
// (PathBerserker2d 寻路跨帧异步,IsMoving 在寻路计算期间为 false,会误触发每帧推进)。
|
||||
// 到达判定对"吸附后的可达点"做,而非原始路点:原始路点可能摆在空中/崖外,
|
||||
// 与之的距离永远进不了到达半径 → 卡死;吸附点是身体站得住的可达点。
|
||||
if (_wpIndex < 0 ||
|
||||
Vector2.Distance(_enemy.transform.position, _waypoints[_wpIndex].position) <= _waypointArriveRadius)
|
||||
Vector2.Distance(_enemy.transform.position, _wpResolvedGoal) <= _waypointArriveRadius)
|
||||
{
|
||||
AdvanceWaypoint();
|
||||
_enemy.MoveTo(_waypoints[_wpIndex].position);
|
||||
SetWaypointGoal();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析当前路点为"身体站得住的可达点"并出发。宽度处理下沉给 Nav 层(<see cref="IPathAgent.ResolveStandablePoint"/>),
|
||||
/// 本层只递原始路点坐标、不感知身体尺寸。吸附失败=路点摆得离导航面太远,显式报错暴露根因,不静默兜底。
|
||||
/// </summary>
|
||||
private void SetWaypointGoal()
|
||||
{
|
||||
Vector2 raw = _waypoints[_wpIndex].position;
|
||||
if (_enemy.Nav == null || !_enemy.Nav.ResolveStandablePoint(raw, out _wpResolvedGoal))
|
||||
{
|
||||
_wpResolvedGoal = raw;
|
||||
Debug.LogWarning($"[EnemyLocomotion] 路点 '{_waypoints[_wpIndex].name}'(index {_wpIndex}) 无法吸附到任何可行走导航段" +
|
||||
"(超出搜索半径)。请检查该路点是否摆放在贴近地面/平台的可行走处。", this);
|
||||
}
|
||||
_enemy.MoveTo(_wpResolvedGoal);
|
||||
}
|
||||
|
||||
private void AdvanceWaypoint()
|
||||
{
|
||||
if (_pingPong)
|
||||
|
||||
Reference in New Issue
Block a user