//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); }
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); }