//populate the cached path of the given AI with the path from startPoint to endPoint private void GeneratePath(int aiAgentIndex, NodeIndex startPoint, NodeIndex endPoint, Node topLevelNode) { bool destinationWithinCurrentNode = startPoint.EqualAtDepth(endPoint, index.GetMaxDepth()); Node start = internalNodes[startPoint.GetIndexAtDepth(index.GetMaxDepth() + 1)]; Node end; if (!destinationWithinCurrentNode) { end = topLevelNode.GetNode(endPoint); } else { end = internalNodes[endPoint.GetIndexAtDepth(index.GetMaxDepth() + 1)]; } //If pathfinding in the lowest layer use the cheaper pathfinding method, else use A* if (startPoint.GetMaxDepth() == index.GetMaxDepth() + 1) { lastPaths[aiAgentIndex] = Pathfinder.GetNextDestNode(start, end, internalNodes, topLevelNode); } else { lastPaths[aiAgentIndex] = Pathfinder.AstarPathfind(start, end, internalNodes); } }
//obtain the next node that the specified AI should move to public Node GetNextDestination(int aiAgentIndex, Node currentPosition) { if (paths == null || paths.Count <= aiAgentIndex) { return(null); } if (paths[aiAgentIndex] == null || paths[aiAgentIndex].Count == 0) { return(null); } //if the current position is null, then the AI is not on any node. Return the start of the path. if (currentPosition == null) { return(topLevelNode.GetNode(paths[aiAgentIndex][0])); } //if the AI is currently on a node, return the last node of the current rigidbody, or the first node of the next rigidbody NodeIndex finalNodeOnCurrentRB = null; for (int i = 0; i < paths[aiAgentIndex].Count; ++i) { if (finalNodeOnCurrentRB == null) { finalNodeOnCurrentRB = paths[aiAgentIndex][i]; } else if (finalNodeOnCurrentRB.EqualAtDepth(paths[aiAgentIndex][i], finalNodeOnCurrentRB.GetMaxDepth() - 1)) { finalNodeOnCurrentRB = paths[aiAgentIndex][i]; } } return(topLevelNode.GetNode(finalNodeOnCurrentRB)); }
//return the path from the start point to the destination point public List <NodeIndex> GetPath(int aiAgentIndex, NodeIndex startPoint, NodeIndex endPoint, Node topLevelNode) { if (lastPaths == null || lastPaths.Count <= aiAgentIndex) { return(null); } if (startPoint == endPoint) { return(null); } //if the start and end point are both in the same child node, delegate to that child int nextDepth = index.GetMaxDepth() + 1; if (startPoint.EqualAtDepth(endPoint, nextDepth)) { if (startPoint.GetIndexAtDepth(nextDepth) >= internalNodes.Count) { return(null); } if (startPoint.GetIndexAtDepth(nextDepth) < 0) { return(null); } return(internalNodes[startPoint.GetIndexAtDepth(nextDepth)].GetPath(aiAgentIndex, startPoint, endPoint, topLevelNode)); } //if there is no cached path for the specified AI if (lastPaths[aiAgentIndex] == null || lastPaths[aiAgentIndex].Count < 1 || lastDestinations[aiAgentIndex] != endPoint || lastOrigins[aiAgentIndex] != startPoint) { bool present = false; //check the cached paths of the other AI's to see if any of them would be suitable for (int i = 0; i < lastOrigins.Count; ++i) { if (i != aiAgentIndex && (lastOrigins[i] == startPoint) && (lastDestinations[i] == endPoint)) { lastPaths[aiAgentIndex] = new List <NodeIndex>(lastPaths[i]); lastOrigins[aiAgentIndex] = startPoint; lastDestinations[aiAgentIndex] = endPoint; i = lastOrigins.Count; present = true; } } //if not then generate the path if (!present) { GeneratePath(aiAgentIndex, startPoint, endPoint, topLevelNode); if (lastPaths[aiAgentIndex] == null || lastPaths[aiAgentIndex].Count < 1) { return(null); } lastDestinations[aiAgentIndex] = endPoint; lastOrigins[aiAgentIndex] = startPoint; } } //if the next level is the deepest level then return this level's path if (startPoint.GetMaxDepth() == nextDepth) { return(lastPaths[aiAgentIndex]); } //If there is only one node in the path then something is wrong, because by this point the start and endpoint should be in different nodes if (lastPaths[aiAgentIndex].Count < 2) { return(null); } int localStart = lastPaths[aiAgentIndex][0].GetIndexAtDepth(nextDepth); NodeIndex localDest = lastPaths[aiAgentIndex][1]; //find the path within the first node of the current level path and return that //Once the path has been found, pathfind within it's first node to determine how to get to the second node of the path return(internalNodes[localStart].GetPath(aiAgentIndex, startPoint, localDest, topLevelNode)); }