/// <summary> /// Called on awake. /// </summary> protected sealed override void OnAwake() { //Determine the cost and path smoothing providers to use ISmoothPaths pathSmoother; var pathSmoothProvider = this.As <IPathSmootherFactory>(); if (pathSmoothProvider == null) { pathSmoother = new PathSmoother(); } else { pathSmoother = pathSmoothProvider.CreateSmoother(); } IMoveCost moveCostProvider; var moveCostProviderFactory = this.As <IMoveCostFactory>(); if (moveCostProviderFactory == null) { if (this.moveCost == CostProviderType.Custom) { this.moveCost = CostProviderType.Diagonal; } switch (this.moveCost) { case CostProviderType.Euclidean: { moveCostProvider = new EuclideanDistance(10); break; } case CostProviderType.Cardinal: { moveCostProvider = new CardinalDistance(10); break; } case CostProviderType.Manhattan: { moveCostProvider = new ManhattanDistance(10); break; } default: { moveCostProvider = new DiagonalDistance(10); break; } } } else { this.moveCost = CostProviderType.Custom; moveCostProvider = moveCostProviderFactory.CreateMoveCostProvider(); } //Setup the pathing engine to use IPathingEngine engine; if (this.engineType == PathingEngineType.Astar) { engine = new PathingAStar(this.initialHeapSize, moveCostProvider, GameServices.cellCostStrategy, pathSmoother); } else { engine = new PathingJumpPointSearch(this.initialHeapSize, moveCostProvider, GameServices.cellCostStrategy, pathSmoother); } _pathService = new PathService(engine, new ThreadFactory(), this.useThreadPoolForAsyncOperations); _pathService.runAsync = this.runAsync; GameServices.pathService = _pathService; }
private PathingStatus StartPathSegment() { if (_requestPreprocessors != null) { for (int i = 0; i < _requestPreprocessors.Length; i++) { if (_requestPreprocessors[i].PreProcess(_segmentRequest)) { break; } } } var fromGrid = GridManager.instance.GetGrid(_segmentRequest.from); var toGrid = GridManager.instance.GetGrid(_segmentRequest.to); var fromPos = new Position(_segmentRequest.from); var toPos = new Position(_segmentRequest.to); //If no grids were resolved for this request it means the request involves two points outside the grid(s) that do not cross any grid(s), so we can move directly between them if (fromGrid == null && toGrid == null) { var pathSegment = new Path(2); pathSegment.Push(toPos); pathSegment.Push(fromPos); _segments.Add(pathSegment); _currentResult.pathCost = _costProvider.GetHeuristic(fromPos, toPos); return(PathingStatus.Complete); } else if (fromGrid == null) { return(PathingStatus.StartOutsideGrid); } var options = _segmentRequest.pathFinderOptions; if (options.optimizeUnobstructedPaths && options.usePathSmoothing && fromGrid == toGrid && !options.preventDiagonalMoves && PathSmoother.CanReducePath(fromPos, toPos, _segmentRequest.requesterProperties, fromGrid.cellMatrix, _cellCostStrategy)) { var pathSegment = new Path(2); pathSegment.Push(toPos); pathSegment.Push(fromPos); _segments.Add(pathSegment); _currentResult.pathCost = _costProvider.GetHeuristic(fromPos, toPos); return(PathingStatus.Complete); } //Just treat the to grid as the from grid in this case so the destination can be closest point on from grid if (toGrid == null) { toGrid = fromGrid; } //Get a reference to the start and end cells var start = fromGrid.GetCell(_segmentRequest.from, false) as IPathNode; _goal = toGrid.GetCell(_segmentRequest.to, false) as IPathNode; //Ensure that the end cell is valid if (_goal == null) { if (options.navigateToNearestIfBlocked) { _goal = toGrid.GetCell(_segmentRequest.to, true) as IPathNode; _segmentRequest.to = _goal.position; } else { return(PathingStatus.EndOutsideGrid); } } if (!_goal.IsWalkableWithClearance(_segmentRequest.requesterProperties) && !options.navigateToNearestIfBlocked) { return(PathingStatus.DestinationBlocked); } //Ensure that the start cell is valid IPathNode actualStart = null; if (!start.IsWalkableWithClearance(_segmentRequest.requesterProperties)) { actualStart = start; start = fromGrid.GetNearestWalkableCell(start.position, _goal.position, true, options.maxEscapeCellDistanceIfOriginBlocked, _segmentRequest.requesterProperties); if (start == null) { return(PathingStatus.NoRouteExists); } } OnStart(start, actualStart); return(PathingStatus.Running); }
/// <summary> /// Called on awake. /// </summary> protected sealed override void OnAwake() { //Determine the cost and path smoothing providers to use ISmoothPaths pathSmoother; var pathSmoothProvider = this.As <IPathSmootherFactory>(); if (pathSmoothProvider == null) { pathSmoother = new PathSmoother(); } else { pathSmoother = pathSmoothProvider.CreateSmoother(); } IMoveCost moveCostProvider; if (this.moveCost == CostProviderType.Custom) { var moveCostProviderFactory = this.As <IMoveCostFactory>(); if (moveCostProviderFactory == null) { moveCostProvider = new DiagonalDistance(10); Debug.LogWarning("Path Service Component: Cost Provider set to Custom but no Cost Provider Factory found!."); } else { moveCostProvider = moveCostProviderFactory.CreateMoveCostProvider(); } } else { switch (this.moveCost) { case CostProviderType.Euclidean: { moveCostProvider = new EuclideanDistance(10); break; } case CostProviderType.Cardinal: { moveCostProvider = new CardinalDistance(10); break; } case CostProviderType.Manhattan: { moveCostProvider = new ManhattanDistance(10); break; } default: { moveCostProvider = new DiagonalDistance(10); break; } } } var preProcessors = this.GetComponents(typeof(IRequestPreProcessor)).Cast <IRequestPreProcessor>().OrderByDescending(p => p.priority).ToArray(); //Setup the pathing engine to use IPathingEngine engine; if (this.engineType == PathingEngineType.Astar) { engine = new PathingAStar(this.initialHeapSize, moveCostProvider, GameServices.cellCostStrategy, pathSmoother, preProcessors); } else { engine = new PathingJumpPointSearch(this.initialHeapSize, moveCostProvider, GameServices.cellCostStrategy, pathSmoother, preProcessors); } _pathService = new PathService(engine, new ThreadFactory(), this.useThreadPoolForAsyncOperations); _pathService.runAsync = this.runAsync; GameServices.pathService = _pathService; }