Пример #1
0
        //make cause system to slow down, use with care
        public static List <Vector3> ForceSearch(NodeTD startN, NodeTD endN, NodeTD blockN, NodeTD[] graph, int footprint = -1)
        {
            if (blockN != null)
            {
                blockN.walkable = false;
            }

            bool pathFound = true;

            int searchCounter = 0;              //used to count the total amount of node that has been searched

            List <NodeTD> closeList = new List <NodeTD>();

            NodeTD[] openList = new NodeTD[graph.Length];

            List <int> openListRemoved = new List <int>();
            int        openListCounter = 0;

            NodeTD currentNode = startN;

            float currentLowestF = Mathf.Infinity;
            int   id             = 0;   //use element num of the node with lowest score in the openlist during the comparison process
            int   i = 0;                //universal int value used for various looping operation

            while (true)
            {
                if (currentNode == endN)
                {
                    break;
                }

                closeList.Add(currentNode);
                currentNode.listState = _ListStateTD.Close;

                currentNode.ProcessNeighbour(endN);

                foreach (NodeTD neighbour in currentNode.neighbourNode)
                {
                    if (neighbour.listState == _ListStateTD.Unassigned && neighbour.walkable)
                    {
                        neighbour.listState = _ListStateTD.Open;
                        if (openListRemoved.Count > 0)
                        {
                            openList[openListRemoved[0]] = neighbour;
                            openListRemoved.RemoveAt(0);
                        }
                        else
                        {
                            openList[openListCounter] = neighbour;
                            openListCounter          += 1;
                        }
                    }
                }

                currentNode = null;

                currentLowestF = Mathf.Infinity;
                id             = 0;
                for (i = 0; i < openListCounter; i++)
                {
                    if (openList[i] != null)
                    {
                        if (openList[i].scoreF < currentLowestF)
                        {
                            currentLowestF = openList[i].scoreF;
                            currentNode    = openList[i];
                            id             = i;
                        }
                    }
                }

                if (currentNode == null)
                {
                    pathFound = false;
                    break;
                }

                openList[id] = null;
                openListRemoved.Add(id);

                searchCounter += 1;
            }


            List <Vector3> p = new List <Vector3>();

            if (pathFound)
            {
                while (currentNode != null)
                {
                    p.Add(currentNode.pos);
                    currentNode = currentNode.parent;
                }

                p = InvertArray(p);
                p = SmoothPath(p);
            }

            if (blockN != null)
            {
                blockN.walkable = true;
            }

            ResetGraph(graph);

            return(p);
        }
Пример #2
0
        IEnumerator _SearchRoutine(NodeTD startN, NodeTD endN, NodeTD[] graph, SetPathCallbackTD callBackFunc)
        {
            //mark that a serac has started, any further query will be queued
            searching = true;
            bool pathFound = true;

            int searchCounter = 0;              //used to count the total amount of node that has been searched
            int loopCounter   = 0;              //used to count how many node has been search in the loop, if it exceed a value, bring it to the next frame
            //float LoopTime=Time.realtimeSinceStartup;

            //closelist, used to store all the node that are on the path
            List <NodeTD> closeList = new List <NodeTD>();

            //openlist, all the possible node that yet to be on the path, the number can only be as much as the number of node in the garph
            NodeTD[] openList = new NodeTD[graph.Length];

            //an array use to record the element number in the open list which is empty after the node is removed to be use as currentNode,
            //so we can use builtin array with fixed length for openlist, also we can loop for the minimal amount of node in every search
            List <int> openListRemoved = new List <int>();
            //current count of elements that are occupied in openlist, openlist[n>openListCounter] are null
            int openListCounter = 0;

            //set start as currentNode
            NodeTD currentNode = startN;

            //use to compare node in the openlist has the lowest score, alwyas set to Infinity when not in used
            float currentLowestF = Mathf.Infinity;
            int   id             = 0;   //use element num of the node with lowest score in the openlist during the comparison process
            int   i = 0;                //universal int value used for various looping operation

            //loop start
            while (true)
            {
                //if we have reach the destination
                if (currentNode == endN)
                {
                    break;
                }

                //for gizmo debug purpose
                //currentNodeBeingProcess=currentNode;

                //move currentNode to closeList;
                closeList.Add(currentNode);
                currentNode.listState = _ListStateTD.Close;

                //loop through the neighbour of current loop, calculate  score and stuff
                currentNode.ProcessNeighbour(endN);

                //put all neighbour in openlist
                foreach (NodeTD neighbour in currentNode.neighbourNode)
                {
                    if (neighbour.listState == _ListStateTD.Unassigned && neighbour.walkable)
                    {
                        //set the node state to open
                        neighbour.listState = _ListStateTD.Open;
                        //if there's an open space in openlist, fill the space
                        if (openListRemoved.Count > 0)
                        {
                            openList[openListRemoved[0]] = neighbour;
                            //remove the number from openListRemoved since this element has now been occupied
                            openListRemoved.RemoveAt(0);
                        }
                        //else just stack on it and increase the occupication counter
                        else
                        {
                            openList[openListCounter] = neighbour;
                            openListCounter          += 1;
                        }
                    }
                }

                //clear the current node, before getting a new one, so we know if there isnt any suitable next node
                currentNode = null;

                //get the next point from openlist, set it as current point
                //just loop through the openlist until we reach the maximum occupication
                //while that, get the node with the lowest score
                currentLowestF = Mathf.Infinity;
                id             = 0;
                for (i = 0; i < openListCounter; i++)
                {
                    if (openList[i] != null)
                    {
                        if (openList[i].scoreF < currentLowestF)
                        {
                            currentLowestF = openList[i].scoreF;
                            currentNode    = openList[i];
                            id             = i;
                        }
                    }
                }

                //if there's no node left in openlist, path doesnt exist
                if (currentNode == null)
                {
                    pathFound = false;
                    break;
                }

                //remove the new currentNode from openlist
                openList[id] = null;
                //put the id into openListRemoved so we know there's an empty element that can be filled in the next loop
                openListRemoved.Add(id);

                //increase the counter
                searchCounter += 1;
                loopCounter   += 1;

                //if exceed the search limit per frame, bring the search to the next frame
                if (loopCounter > ScanNodeLimitPerFrame)
                {
                    loopCounter = 0;                    //reset the loopCounter for the next frame
                    yield return(null);
                }
            }


            //trace back the path through closeList
            List <Vector3> p = new List <Vector3>();

            if (pathFound)
            {
                //track back the node's parent to form a path
                while (currentNode != null)
                {
                    p.Add(currentNode.pos);
                    currentNode = currentNode.parent;
                }

                //since the path is now tracked from endN ot startN, invert the list
                p = InvertArray(p);
                p = SmoothPath(p);
            }

            callBackFunc(p);

            //clear searching so indicate the search has end and a new serach can be called
            searching = false;

            ResetGraph(graph);
        }