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:
@@ -620,6 +620,33 @@ namespace PathBerserker2d
|
||||
return PathTo(goal);
|
||||
}
|
||||
|
||||
// [项目新增] 目标点吸附:把任意世界点映射到最近的、agent 容身得下的可行走段上,再按 endMargin
|
||||
// 从段两端内缩,得到"身体真正站得住"的世界点(避免落在角色宽度站不住的崖沿被移动层夹停)。
|
||||
// 与 SetRandomDestinationOnCurrentSegment 同源:endMargin 传 agent 半宽 + 落崖检测余量。
|
||||
// 段短于 2*endMargin → 退化到中点。searchRadius 内映射不到任何段(目标离导航面太远)时返回 false。
|
||||
/// <summary>
|
||||
/// Maps <paramref name="worldTarget"/> to the nearest walkable segment the agent fits on,
|
||||
/// then insets by <paramref name="endMargin"/> from BOTH segment ends so the returned point is
|
||||
/// one a bodied agent can actually stand on (not clamped at a ledge). A segment shorter than
|
||||
/// 2*endMargin degenerates to its midpoint. Returns false (and echoes worldTarget) if nothing
|
||||
/// maps within <paramref name="searchRadius"/>.
|
||||
/// </summary>
|
||||
public bool TryGetStandablePointNear(Vector2 worldTarget, float searchRadius, float endMargin, out Vector2 standable)
|
||||
{
|
||||
if (!PBWorld.TryMapPoint(worldTarget, searchRadius, this, out var ptr))
|
||||
{
|
||||
standable = worldTarget;
|
||||
return false;
|
||||
}
|
||||
|
||||
var cluster = ptr.cluster;
|
||||
float len = cluster.Length;
|
||||
float m = Mathf.Clamp(endMargin, 0f, len * 0.5f); // 段太短 → 退化到中点
|
||||
float t = Mathf.Clamp(ptr.t, m, len - m);
|
||||
standable = cluster.owner.LocalToWorld.MultiplyPoint3x4(cluster.GetPositionAlongSegment(t));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// If you implement link traversal yourself, call this to complete a link traversal.
|
||||
|
||||
Reference in New Issue
Block a user