예제 #1
0
    /* This will find a path from To - From if it exists
     * If it succeeds it will return a list of Waypoints, tile by tile, which if followed will lead to the destination
     * If it fails the list will be empty
     * Any non null entry in the array will block the movement
     * if Debug is true , this will draw DebugDots on the path
     */

    public List <Waypoint> Find(Waypoint vFrom, Waypoint vTo, GameObject[,] vMap, bool vDebug = false)
    {
        mOpen        = new List <Node> (); //Keep a list of open paths to explore
        mClosed      = new List <Node> (); //List of closed paths, I.E. ones which have been explored
        mMap         = vMap;               //Keep a pointer to the map of blocking tiles
        mDestination = new Node(vTo);      //Make a destination node, so we can check we have arrived
        mWidth       = mMap.GetLength(0);  //Cache size of map to make bounds check faster
        mHeight      = mMap.GetLength(1);
        mNeighbours  = SetNeighbours();    //Cache list of relative neighbours, only happens first time as its static
        Node tCurrent = new Node(vFrom);   //Add starting node to the Open list

        mOpen.Add(tCurrent);               //Add starting point
        mDebug = vDebug;                   //Should we draw debug circles
        if (mDebug)
        {
            DebugHelper.DebugDot(vFrom.X, vFrom.Y, Color.yellow, mSlowDotFade); //Show starting position
            DebugHelper.DebugDot(vTo.X, vTo.Y, Color.cyan, mSlowDotFade);       //Show finish position
        }
        return(CalculatePath());                                                //Run A*
    }
예제 #2
0
    public List <Waypoint> CalculatePath()              //Main A* routine, makes a path to the target
    {
        bool            Quit  = false;                  //Used to exit infinite loop when debugging, set to true to stop Unity locking up
        List <Waypoint> tPath = new List <Waypoint>();  //List for storing found path

        do
        {
            Node tShortNode = FindShortOpen();      //Find current open path with shortest F
            mOpen.Remove(tShortNode);               //Move it to closed list
            mClosed.Add(tShortNode);                //
            if (mDebug)                             //Draw a Dot to show current path progress
            {
                DebugHelper.DebugDot(tShortNode.X, tShortNode.Y, Color.gray, mFastDotFade);
            }
            Node tAtDestination = IsInClosed(mDestination);     //Check if we have reached the destination
            if (tAtDestination != null)                         //If the destination is in closed list we are there
            {
                Node tNext;
                do                                                         //Construct list of waypoints for caller
                {
                    tNext = tAtDestination.Parent;                         //Follow links from destination to start (reverse order)
                    if (tNext != null)                                     //We dont need to include start position and when we have reached it parent will be null and list is complete
                    {
                        Waypoint tWayPoint = new Waypoint(tAtDestination); //Add waypoint from current Destination as we walk the list back to the origin
                        if (mDebug)                                        //Show Path if debugging
                        {
                            DebugHelper.DebugDot(tWayPoint.X, tWayPoint.Y, Color.red, mSlowDotFade);
                        }
                        tPath.Insert(0, tWayPoint);     //Add waypoint, by adding at start of list we are reversing the Node list, which is what we want as its back to front when generated
                        //ie. the nodes go from the end point to the start
                        tAtDestination = tNext;         //Following the parent reference will take us back to the start
                    }
                    else
                    {
                        break;          //Done, we can leave the loop
                    }
                } while (true);
                mOpen        = null;                    //Release resources
                mClosed      = null;
                mDestination = null;
                return(tPath);                                 //Send Path to caller
            }
            List <Node> tWalkableNodes = Walkable(tShortNode); //If we are not there yet, find all walkable squares centered around current position
            foreach (Node tCurrent in tWalkableNodes)
            {
                if (IsInClosed(tCurrent) != null)                                       //If we have this square in closed list already, we can skip it
                {
                    continue;
                }
                Node tOpen = IsInOpen(tCurrent);                        //If its in open list get it
                if (tOpen == null)
                {
                    mOpen.Add(tCurrent);                    //Add to new open list if its not already there
                }
                else
                {
                    tOpen.UpdateIfCloser(tCurrent);                                     //If we have it check if this one would give a better F Score (by having a lower G), if so replace & reparent
                }
            }
        } while (mOpen.Count > 0 && !Quit); //Keep going while we have open destinations, if there are none, it his means the path does not exist, also allow debugger to exit by setting Quit true, stops Unity Hanging
        return(tPath);                      //If we get here we are going to return an empty path, as success exit is higher up
    }