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: