Esempio n. 1
0
        /// <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;
        }