diff --git a/Assets/PathBerserker2d/Scripts/PathBerserker2d/NavAgent/NavAgent.cs b/Assets/PathBerserker2d/Scripts/PathBerserker2d/NavAgent/NavAgent.cs
index aa90f606..29935f3a 100644
--- a/Assets/PathBerserker2d/Scripts/PathBerserker2d/NavAgent/NavAgent.cs
+++ b/Assets/PathBerserker2d/Scripts/PathBerserker2d/NavAgent/NavAgent.cs
@@ -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;
}
+ ///
+ /// After the most recent failed path request (NoPathFromStartToGoal), returns the closest
+ /// reachable world position found towards the goal. Returns false if none is available.
+ ///
+ 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() { currentPathRequest.closestReachablePosition });
}
- OnFailedToFindPath?.Invoke(this);
+ RaiseFailedToFindPath(currentPathRequest);
}
break;
case PathRequest.RequestState.Finished: