예제 #1
0
        public static void RequestPath(PathRequest request)
        {
            ThreadStart threadStart = delegate
            {
                instance.pathFinding.FindPath(request, instance.FinishedProcessingPath);
            };

            threadStart.Invoke();
        }
예제 #2
0
        public void RequestPath(PathRequest request) // this should be static
        {
            ThreadStart threadStart = delegate
            {
                pathFinding.FindPath(request, FinishedProcessingPath);
            };

            threadStart.Invoke();
        }
예제 #3
0
        public void RequestSimulatePath(PathRequest request) // this should be static
        {
            ThreadStart threadStart = delegate
            {
                StopAllCoroutines();
                StartCoroutine(pathFinding.FindPathSimulation(request, FinishedProcessingPath));
            };

            threadStart.Invoke();
        }
        //changing to IEnumerator
        // Main A* algo



        /*
         * A* Search Algorithm From G4G
         * 1.  Initialize the open list
         * 2.  Initialize the closed list
         * put the starting node on the open
         * list (you can leave its f at zero)
         *
         * 3.  while the open list is not empty
         * a) find the node with the least f on
         * the open list, call it "q"
         *
         * b) pop q off the open list
         *
         * c) generate q's 8 successors and set their
         *  parents to q
         *
         * d) for each successor
         * i) if successor is the goal, stop search
         * successor.g = q.g + distance between
         *                    successor and q
         * successor.h = distance from goal to
         * successor
         * successor.f = successor.g + successor.h
         *
         * ii) if a node with the same position as
         *  successor is in the OPEN list which has a
         * lower f than successor, skip this successor
         *
         * iii) if a node with the same position as
         *  successor  is in the CLOSED list which has
         *  a lower f than successor, skip this successor
         *  otherwise, add  the node to the open list
         * end (for loop)
         *
         * e) push q on the closed list
         * end (while loop)
         */
        public void FindPath(PathRequest request, Action <PathResult> callback) //public void FindPath(Vector3 startPosition, Vector3 targetPosition)
        {
            FieldNode startNode = grid.NodeFromFieldGrid(request.pathStart);
            FieldNode endNode   = grid.NodeFromFieldGrid(request.pathEnd);


            Stopwatch sw = new Stopwatch();

            sw.Start();

            Vector3[] waypoints   = new Vector3[0];
            bool      pathSuccess = false;

            // check if startNode and endNode is in a placeable node
            if (startNode.isPlaceable && endNode.isPlaceable)
            {
                Heap <FieldNode>    openSet   = new Heap <FieldNode>(grid.MaxSize); // List for unoptimized version
                HashSet <FieldNode> closedSet = new HashSet <FieldNode>();

                openSet.Add(startNode);

                while (openSet.Count > 0)
                {
                    /*push q on the closed list
                     * end */
                    FieldNode currentNode = openSet.RemoveFirst();


                    closedSet.Add(currentNode);

                    if (currentNode == endNode)
                    {
                        sw.Stop();
                        print(this.transform.name + " path Found " + sw.ElapsedMilliseconds + "ms");
                        pathSuccess = true;
                        // TracePath(startNode, endNode);
                        break;
                        // return;
                    }
                    // calculate gCost and hCost
                    // by nearest neighbor
                    foreach (FieldNode neighbor in grid.GetNeighbors(currentNode))
                    {
                        if (!neighbor.isPlaceable || closedSet.Contains(neighbor))
                        {
                            continue;
                        }

                        int newMovementCostToNeighbor = currentNode.gCost + GetDistance(currentNode, neighbor) + neighbor.movementPenalty;
                        if (newMovementCostToNeighbor < neighbor.gCost || !openSet.Contains(neighbor))
                        {
                            neighbor.gCost  = newMovementCostToNeighbor;
                            neighbor.hCost  = GetDistance(neighbor, endNode);
                            neighbor.parent = currentNode;

                            if (!openSet.Contains(neighbor))
                            {
                                openSet.Add(neighbor);
                            }
                            else
                            {
                                openSet.UpdateItem(neighbor);
                            }
                        }
                    }
                }
            }
            if (pathSuccess)
            {
                waypoints = TracePath(startNode, endNode);

                pathSuccess = waypoints.Length > 0;
            }
            callback(new PathResult(waypoints, pathSuccess, request.callBack));
        }
        // Change to IEnumerator

        public IEnumerator FindPathSimulation(PathRequest request, Action <PathResult> callback) //public void FindPath(Vector3 startPosition, Vector3 targetPosition)
        {
            FieldNode startNode = grid.NodeFromFieldGrid(request.pathStart);

            Spawn.instance.placeVisualCloseNode(startNode);
            yield return(new WaitForSecondsRealtime(timeScale));

            FieldNode endNode = grid.NodeFromFieldGrid(request.pathEnd);

            Spawn.instance.placeVisualCloseNode(endNode);
            yield return(new WaitForSeconds(timeScale));


            Stopwatch sw = new Stopwatch();

            sw.Start();

            Vector3[] waypoints   = new Vector3[0];
            bool      pathSuccess = false;


            if (startNode.isPlaceable && endNode.isPlaceable)
            {
                Heap <FieldNode>    openSet   = new Heap <FieldNode>(grid.MaxSize); // List for unoptimized version
                HashSet <FieldNode> closedSet = new HashSet <FieldNode>();

                openSet.Add(startNode);

                while (openSet.Count > 0)
                {
                    FieldNode currentNode = openSet.RemoveFirst();

                    closedSet.Add(currentNode);
                    Spawn.instance.placeVisualOpenNode(currentNode);
                    yield return(new WaitForSeconds(timeScale));

                    if (currentNode == endNode)
                    {
                        sw.Stop();
                        print(this.transform.name + " path Found " + sw.ElapsedMilliseconds + "ms");
                        pathSuccess = true;
                        // foreach (FieldNode n in closedSet)
                        // {
                        //     Spawn.instance.placeVisualCloseNode(n);
                        //     yield return new WaitForSeconds(timeScale);
                        // }

                        // TracePath(startNode, endNode);
                        Spawn.instance.placeVisualCloseNode(endNode);
                        yield return(new WaitForSeconds(timeScale));

                        break;
                        // return;
                    }
                    foreach (FieldNode neighbor in grid.GetNeighbors(currentNode))
                    {
                        if (!neighbor.isPlaceable || closedSet.Contains(neighbor))
                        {
                            Spawn.instance.placeVisualCloseNode(neighbor);
                            yield return(new WaitForSeconds(timeScale));

                            continue;
                        }
                        int newMovementCostToNeighbor = currentNode.gCost + GetDistance(currentNode, neighbor) + neighbor.movementPenalty;
                        if (newMovementCostToNeighbor < neighbor.gCost || !openSet.Contains(neighbor))
                        {
                            neighbor.gCost  = newMovementCostToNeighbor;
                            neighbor.hCost  = GetDistance(neighbor, endNode);
                            neighbor.parent = currentNode;

                            if (!openSet.Contains(neighbor))
                            {
                                openSet.Add(neighbor);
                            }
                            else
                            {
                                openSet.UpdateItem(neighbor);
                            }
                            Spawn.instance.placeVisualOpenNode(neighbor);
                            yield return(new WaitForSeconds(timeScale));
                        }
                    }
                }
            }
            if (pathSuccess)
            {
                waypoints = SimulateTracePath(startNode, endNode);
                Spawn.instance.placeVisualPathNode(startNode);
                yield return(new WaitForSeconds(timeScale));

                pathSuccess = waypoints.Length > 0;
                foreach (Vector3 waypoint in waypoints)
                {
                    Spawn.instance.placeVisualPathNode(waypoint);
                    yield return(new WaitForSeconds(timeScale));
                }
                Spawn.instance.placeVisualPathNode(endNode);
                yield return(new WaitForSeconds(timeScale));
            }
            callback(new PathResult(waypoints, pathSuccess, request.callBack));
            yield return(null);
        }