예제 #1
0
        public void FindPath(int requestId, Vector3 startPoint, Vector3 endPoint, PathfindingComplete callback, List <string> ignoreTemplateList = null)
        {
            GridCell startCell = GridManager.Instance.GetCell(startPoint);
            GridCell endCell   = GridManager.Instance.GetCell(endPoint);

            if (startCell == null || endCell == null)
            {
                PathData pathData = new PathData(new Vector3[1] {
                    endPoint
                }, new List <Node>(1)
                {
                    null
                });
                callback(false, pathData);
                return;
            }

            PathRequestData prd = new PathRequestData(startCell, endCell, callback, ignoreTemplateList);

            if (_pathRequestDictionary.ContainsKey(requestId))
            {
                _pathRequestDictionary[requestId] = prd;
            }
            else
            {
                _pathRequestQueue.Enqueue(requestId);
                _pathRequestDictionary.Add(requestId, prd);
            }
        }
예제 #2
0
        private void FindPathInternal(int requestId)
        {
            bool pathFound = false;

            PathRequestData prd      = _pathRequestDictionary[requestId];
            PathData        pathData = null;

            Node startNode = Nodes[prd.startCell.GridPosition.x, prd.startCell.GridPosition.y];
            Node endNode   = Nodes[prd.endCell.GridPosition.x, prd.endCell.GridPosition.y];

            Heap <Node>    openSet  = new Heap <Node>(_gridWidth * _gridHeight);
            HashSet <Node> closeSet = new HashSet <Node>();

            openSet.Add(startNode);

            while (openSet.Count > 0)
            {
                Node currentNode = openSet.RemoveFirst();
                closeSet.Add(currentNode);

                if (currentNode == endNode)
                {
                    var       retracedPath = RetracePath(startNode, endNode);
                    Vector3[] waypoints    = PathToVector3Array(retracedPath);

                    if (waypoints == null)
                    {
                        retracedPath.Add(endNode);
                        waypoints = new Vector3[1] {
                            endNode.CellObj.transform.position
                        };
                    }

                    pathData = new PathData(waypoints, retracedPath);
                    prd.callback(true, pathData);
                    pathFound = true;
                    break;
                }


                foreach (Node neighbour in GetNeighbours(currentNode))
                {
                    if (closeSet.Contains(neighbour))
                    {
                        continue;
                    }

                    int hCostToNeighbor = neighbour.CellObj.Cost;

                    if (prd.ignoreTemplateList != null && neighbour.CellObj.IsOccupied)
                    {
                        if (prd.ignoreTemplateList.Count(template => template.Equals(neighbour.CellObj.Occupant.TemplateID)) > 0)
                        {
                            hCostToNeighbor = 1;
                        }
                    }

                    int movementCostToNeighbour = currentNode.GCost + hCostToNeighbor;

                    if (movementCostToNeighbour < neighbour.GCost || !openSet.Contains(neighbour))
                    {
                        neighbour.GCost = movementCostToNeighbour;
                        neighbour.HCost = GetDistance(neighbour, endNode);

                        neighbour.Parent = currentNode;

                        if (!openSet.Contains(neighbour))
                        {
                            openSet.Add(neighbour);
                        }
                        else
                        {
                            openSet.UpdateItem(neighbour);
                        }
                    }
                }
            }

            if (!pathFound)
            {
                pathData = new PathData(new Vector3[1] {
                    endNode.CellObj.transform.position
                }, new List <Node>(1)
                {
                    endNode
                });
                prd.callback(false, pathData);
            }

            _pathRequestDictionary.Remove(requestId);
        }