void FindPath(Vector2 startPosition, Vector2 targetPosition) { PathfindingNode startNode = grid.GetNodeFromWorldPoint(startPosition); PathfindingNode targetNode = grid.GetNodeFromWorldPoint(targetPosition); List <PathfindingNode> openSet = new List <PathfindingNode>(); HashSet <PathfindingNode> closedSet = new HashSet <PathfindingNode>(); openSet.Add(startNode); while (openSet.Count > 0) { PathfindingNode currentNode = openSet[0]; for (int i = 0; i < openSet.Count; i++) { if (openSet[i].fCost < currentNode.fCost || openSet[i].fCost == currentNode.fCost) { if (openSet[i].hCost < currentNode.hCost) { currentNode = openSet[i]; } } openSet.Remove(currentNode); closedSet.Add(currentNode); if (currentNode == targetNode) { RetracePath(startNode, targetNode); return; } foreach (PathfindingNode neighbor in grid.GetNeighbors(currentNode)) { if (!neighbor.isWalkable || closedSet.Contains(neighbor)) { continue; } int newMovementCostToNeighbor = currentNode.gCost + GetDistance(currentNode, neighbor); if (newMovementCostToNeighbor < neighbor.gCost || !openSet.Contains(neighbor)) { neighbor.gCost = newMovementCostToNeighbor; neighbor.hCost = GetDistance(neighbor, targetNode); neighbor.parent = currentNode; if (!openSet.Contains(neighbor)) { openSet.Add(neighbor); } } } } } }
/// <summary> /// Finds a path using A* /// </summary> /// <param name="startPosition">The starting position of the agent.</param> /// <param name="targetPosition">The target position.</param> private void PathAStar(Vector3 startPosition, Vector3 targetPosition) { //Get both nodes from the given world positions, start and target. Node startNode = grid.NodeFromWorldPosition(startPosition); Node targetNode = grid.NodeFromWorldPosition(targetPosition); //Initialize open and closed set. List <Node> openSet = new List <Node>(); HashSet <Node> closedSet = new HashSet <Node>(); bool success = false; //First add starting node to the open set. openSet.Add(startNode); //Only loop while the open set has nodes. while (openSet.Count > 0) { Node curNode = openSet[0]; for (int i = 1; i < openSet.Count; i++) { if ((openSet[i].fCost < curNode.fCost || openSet[i].fCost == curNode.fCost) && openSet[i].hCost < curNode.hCost) { //If the fCost of the node in open set is less than the current node. curNode = openSet[i]; //Since the cost of that node is less, thats the node we want. (Shortest path) } } //Now that the current node is set to the node with the lowest fCost, remove it from open set and put in closed set. openSet.Remove(curNode); closedSet.Add(curNode); if (curNode == targetNode) { //If the current node is equal to the target node, we reached the destination. success = true; break; } //Get the neighbors of the current node. List <Node> neighbors = grid.GetNeighbors(curNode); //Loops through each of the current nodes neighbors. foreach (Node neighborNode in neighbors) { //if the neighbor is not walkable or the neighbor is in the closed set, skip to next neighbor. if (!neighborNode.walkable || closedSet.Contains(neighborNode)) { continue; } int newCost = curNode.gCost + GetManhattenDistance(neighborNode, targetNode); if (newCost < neighborNode.gCost || !openSet.Contains(neighborNode)) { //Assign new values to neighbor node. neighborNode.gCost = newCost; neighborNode.hCost = GetManhattenDistance(neighborNode, targetNode); neighborNode.parent = curNode; //If a neighboring node is not in the open set add it to be explored. if (!openSet.Contains(neighborNode)) { openSet.Add(neighborNode); } } } } Vector3[] pathPoints = new Vector3[0]; if (success) { pathPoints = GetPath(startNode, targetNode); } rm.FinishedProcessing(pathPoints, success); }