feat(nav): NavAgent 暴露寻路失败时的最近可达点 TryGetClosestReachablePosition

This commit is contained in:
2026-07-23 16:52:28 +08:00
parent a60073d92c
commit 4079392a79
@@ -365,6 +365,9 @@ namespace PathBerserker2d
private bool traversedLinkSinceLastPath;
private bool stopRequested;
// [项目新增] 上次寻路失败(NoPathFromStartToGoal)时算出的最近可达点,供执行层"寻路到最近可到达点"读取。
private NavSegmentPositionPointer _lastClosestReachable = NavSegmentPositionPointer.Invalid;
#region UNITY_METHODS
private void OnEnable()
{
@@ -837,6 +840,31 @@ namespace PathBerserker2d
return pr.Status == PathRequest.RequestState.Finished;
}
/// <summary>
/// After the most recent failed path request (NoPathFromStartToGoal), returns the closest
/// reachable world position found towards the goal. Returns false if none is available.
/// </summary>
public bool TryGetClosestReachablePosition(out Vector2 worldPos)
{
if (!_lastClosestReachable.IsInvalid())
{
worldPos = _lastClosestReachable.Position;
return true;
}
worldPos = Vector2.zero;
return false;
}
// [项目新增] 记录失败请求的最近可达点后再广播寻路失败,供执行层读取。仅 NoPath 失败才有最近点。
private void RaiseFailedToFindPath(PathRequest failedRequest)
{
_lastClosestReachable = (failedRequest != null
&& failedRequest.FailReason == PathRequest.RequestFailReason.NoPathFromStartToGoal)
? failedRequest.closestReachablePosition
: NavSegmentPositionPointer.Invalid;
OnFailedToFindPath?.Invoke(this);
}
private int GetNavTagMask()
{
int navTagMask = 0;
@@ -924,7 +952,7 @@ namespace PathBerserker2d
|| repathPathRequest.FailReason == PathRequest.RequestFailReason.WorldWasDestroyed)
{
Stop();
OnFailedToFindPath?.Invoke(this);
RaiseFailedToFindPath(repathPathRequest);
}
repathPathRequest.Reset();
@@ -953,7 +981,7 @@ namespace PathBerserker2d
if (currentPathRequest.Status == PathRequest.RequestState.Failed && enableDebugMessages)
Debug.Log($"{name}: Pathrequest failed because: {currentPathRequest.FailReason}");
OnFailedToFindPath?.Invoke(this);
RaiseFailedToFindPath(currentPathRequest);
currentPathRequest.Reset();
}
else if (currentPathRequest.FailReason == PathRequest.RequestFailReason.NoPathFromStartToGoal && !currentPathRequest.closestReachablePosition.IsInvalid())
@@ -964,7 +992,7 @@ namespace PathBerserker2d
{
UpdatePath(new List<NavSegmentPositionPointer>() { currentPathRequest.closestReachablePosition });
}
OnFailedToFindPath?.Invoke(this);
RaiseFailedToFindPath(currentPathRequest);
}
break;
case PathRequest.RequestState.Finished: