public void Set(NPathPlanParams planParams, NPool <NPathPlanner> .NNode pathPlanner, NIPathAgent agent) { m_pathPlanParams = planParams; m_pathPlanner = pathPlanner; m_replanTimeRemaining = planParams.ReplanInterval; m_agent = agent; }
public override void Awake(int maxNumberOfNodes) { base.Awake(maxNumberOfNodes); m_openNodes = new NBinaryHeap <NNode>(); m_openNodes.Capacity = maxNumberOfNodes; m_nodePool = new NPool <NNode>(maxNumberOfNodes); m_expandedNodes = new Dictionary <int, NPool <NNode> .NNode>(maxNumberOfNodes); m_solution = new LinkedList <NNode>(); m_reachedGoalNodeSuccessCondition = new ReachedGoalNode_SuccessCondition(); }
protected NPool <NNode> .NNode CreateNode(int nodeIndex) { System.Diagnostics.Debug.Assert(m_nodePool.ActiveCount == m_expandedNodes.Count); NPool <NNode> .NNode newNode = m_nodePool.Get(); m_expandedNodes[nodeIndex] = newNode; NNode.eState nodeState = NNode.eState.kUnvisited; if (World.IsNodeBlocked(nodeIndex)) { nodeState = NNode.eState.kBlocked; } newNode.Item.Awake(nodeIndex, nodeState); System.Diagnostics.Debug.Assert(m_nodePool.ActiveCount == m_expandedNodes.Count); return(newNode); }
/// <summary> /// Update the current path plan by running a single cycle of the A* search. A "single A* cycle" /// expands a single node, and all of its neighbors. To run a full A* search, just run this function /// repeatedly until the function returns kSuccessfullySolvedPath, or kFailedToSolvePath. /// Note that the openNodes variable is a binary heap data structure. /// /// Assumptions: The start node has already been added to the openNodes, and the start node is the only node currently /// stored inside openNodes. /// </summary> /// <returns> /// Return the status of the path being solved. The path has either been solved, we failed to solve the path, or /// we are still in progress of solving the path. /// </returns> protected ePlanStatus RunSingleAStarCycle() { // Note: This failure condition must be tested BEFORE we remove an item from the open heap. if (m_openNodes.Count == 0) { return(ePlanStatus.kPlanFailed); } // The current least costing pathnode is considered the "current node", which gets removed from the open list and added to the closed list. NNode currentNode = m_openNodes.Remove(); CloseNode(currentNode); if (PlanSucceeded(currentNode)) { ConstructSolution(); return(ePlanStatus.kPlanSucceeded); } else if (PlanFailed(currentNode)) { return(ePlanStatus.kPlanFailed); } int[] neighbors = null; int numNeighbors = World.GetNeighbors(currentNode.Index, ref neighbors); for (int i = 0; i < numNeighbors; i++) { float actualCostFromCurrentNodeToNeighbor, testCost; int neighborIndex = neighbors[i]; if (neighborIndex == NNode.kInvalidIndex) { // This neighbor is off the map. continue; } NPool <NNode> .NNode neighbor = GetNode(neighborIndex); if (m_expandedNodes.Count == m_maxNumberOfNodes) { UnityEngine.Debug.LogWarning("Pathplan failed because it reached the max node count. Try increasing " + "the Max Number Of Nodes Per Planner variable on the PathManager, through " + "the Inspector window."); return(ePlanStatus.kPlanFailed); } switch (neighbor.Item.State) { case NNode.eState.kBlocked: case NNode.eState.kClosed: // Case 1: Ignore continue; case NNode.eState.kUnvisited: // Case 2: Add to open list RecordParentNodeAndPathCosts(neighbor.Item, currentNode); OpenNode(neighbor.Item); break; case NNode.eState.kOpen: // Case 3: Update scores actualCostFromCurrentNodeToNeighbor = World.GetGCost(currentNode.Index, neighbor.Item.Index); testCost = currentNode.G + actualCostFromCurrentNodeToNeighbor; if (testCost < neighbor.Item.G) { RecordParentNodeAndPathCosts(neighbor.Item, currentNode); // Maintain the heap property. m_openNodes.Remove(neighbor.Item); m_openNodes.Add(neighbor.Item); } break; default: System.Diagnostics.Debug.Assert(false, "PathNode is in an invalid state when running a single cycle of A*"); break; } ; } return(ePlanStatus.kPlanning); }