From 4079392a7993b867180701d2979fd0f99f65f43d Mon Sep 17 00:00:00 2001 From: Joywayer Date: Thu, 23 Jul 2026 16:52:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(nav):=20NavAgent=20=E6=9A=B4=E9=9C=B2?= =?UTF-8?q?=E5=AF=BB=E8=B7=AF=E5=A4=B1=E8=B4=A5=E6=97=B6=E7=9A=84=E6=9C=80?= =?UTF-8?q?=E8=BF=91=E5=8F=AF=E8=BE=BE=E7=82=B9=20TryGetClosestReachablePo?= =?UTF-8?q?sition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PathBerserker2d/NavAgent/NavAgent.cs | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) 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: