/// <summary> /// Starts pathfinding task from <paramref name="startPos" /> to <paramref name="targetPos" /> asyncronously. /// </summary> /// <param name="startPos">Coordinate of the start pathfinding point at space.</param> /// <param name="targetPos">Coordinate of the target pathfinding point at space.</param> /// <param name="pathfindingLvl">Level of the pathfinding graph, which pathfinding will performed on.</param> /// <param name="foundPath">Variable, which found path will puted in.</param> /// <param name="usingAlg">Algorithm, that must be using for pathfinding.</param> /// <param name="failurePathfindingActions">Instructions, that must be invoked in the case, when pathfinding unsucced.</param> /// <param name="succesPathfindingActions">Instructions, that must be invoked in the case, when pathfinding succed.</param> /// <param name="inThreadOptimization">Is needed to perform finden path optimization?</param> /// <param name="inThreadSmoothing">Is needed to perform finden path smoothing?</param> public void FindWay(Vector3 startPos, Vector3 targetPos, int pathfindingLvl, List <Vector3> foundPath, PathfindingAlgorithm usingAlg, Action failurePathfindingActions = null, Action succesPathfindingActions = null, bool inThreadOptimization = false, bool inThreadSmoothing = false) { if (!spaceManagerInstance.isPrimaryProcessingCompleted) { throw new GraphNotReadyException(); } if (pathfindingLevel >= spaceManagerInstance.gridDetailLevelsCount || pathfindingLevel < 0) { throw new PathfindingLevelOutOfRangeException(); } PathfindingParamContainer pathfindingData = new PathfindingParamContainer { start = startPos, target = targetPos, outPath = foundPath, usingAlg = selectedPFAlg, pathfindingLevel = pathfindingLvl, inThreadOptimizePath = inThreadOptimization, inThreadSmoothPath = inThreadSmoothing, failureActions = failurePathfindingActions, succesActions = succesPathfindingActions, generateEvents = true }; ThreadPool.QueueUserWorkItem(PathfindingThreadMethod, pathfindingData); }
/// <summary> /// Internal method. /// Performs pathfinding. /// (asynchronous execution is assumed) /// </summary> /// <param name="inpData"></param> void PathfindingThreadMethod(object inpData) { PathfindingParamContainer paramsData = (PathfindingParamContainer)inpData; try { if (paramsData.generateEvents) { if (!IsAtConstraintsArea(paramsData.target)) { lock (actionsQueue) actionsQueue.Enqueue(new Action(() => { curCond = WaitingForRequest; ThrowUniversalEvent("EventPathfindingToOutwardPointRequested"); })); return; } if (!IsAtConstraintsArea(paramsData.start)) { actionsQueue.Enqueue(new Action(() => { curCond = WaitingForRequest; ThrowUniversalEvent("EventPathfindingFromOutwardPointRequested"); })); return; } if (SpaceGraph.IsCellOccStaticOnLevel(paramsData.start, 0)) { actionsQueue.Enqueue(new Action(() => { curCond = WaitingForRequest; ThrowUniversalEvent("EventPathfindingFromStaticOccupiedCellRequested"); })); return; } if (SpaceGraph.IsCellOccStaticOnLevel(paramsData.target, 0)) { actionsQueue.Enqueue(new Action(() => { curCond = WaitingForRequest; ThrowUniversalEvent("EventPathfindingToStaticOccupiedCellRequested"); })); return; } } List <Vector3> foundPath; // поиск пути, результат кладется в переменную foundPath if (paramsData.usingAlg == PathfindingAlgorithm.AStar) { Graph graph = new Graph(spaceManagerInstance, cTSInstance.Token, paramsData.start, paramsData.target, paramsData.pathfindingLevel, new SpaceConstraints { xMin = xMin, xMax = xMax, yMin = yMin, yMax = yMax, zMin = zMin, zMax = zMax }, heuristicFactor ); foundPath = graph.GetWay(); } else { WaveTrace waveTraceInst = new WaveTrace( new SpaceConstraints { xMin = xMin, xMax = xMax, yMin = yMin, yMax = yMax, zMin = zMin, zMax = zMax }, cTSInstance.Token, paramsData.start, paramsData.target); waves = waveTraceInst.waves; foundPath = waveTraceInst.GetWay(); } if (foundPath == null) { lock (actionsQueue) actionsQueue.Enqueue(paramsData.failureActions); return; } if (paramsData.inThreadOptimizePath) { foundPath = PathHandler.PathFancification(foundPath, paramsData.pathfindingLevel); foundPath = PathHandler.PathOptimization(foundPath, paramsData.pathfindingLevel); } if (paramsData.inThreadSmoothPath) { foundPath = PathHandler.PathSmoothing(foundPath, paramsData.pathfindingLevel); } if (paramsData.inThreadOptimizePath || paramsData.inThreadSmoothPath) { totalLength = 0; for (int i = 0; i < foundPath.Count - 1; i++) { totalLength += Vector3.Distance(foundPath[i], foundPath[i + 1]); } } lock (paramsData.outPath) { paramsData.outPath.Clear(); paramsData.outPath.AddRange(foundPath); } lock (actionsQueue) actionsQueue.Enqueue(paramsData.succesActions); } catch (Exception ex) { UnityEngine.Debug.Log(ex.Message); } }