/// <summary> /// Finds a path from start to end. /// </summary> /// <param name="start">a start position</param> /// <param name="target">a target position</param> /// <returns></returns> public List <Node> FindPath(Vector3 start, Vector3 target) { Heap <Node> openSet = new Heap <Node>(totalNodes); List <Node> closedSet = new List <Node>(); List <Node> path = new List <Node>(); Node startNode = grid.GetNodeFromWorldPos(start); Node targetNode = grid.GetNodeFromWorldPos(target); // Returns an empty path if either of the ends is invalid if (startNode == null || targetNode == null || startNode.isBlocked || targetNode.isBlocked) { return(path); } startNode.gCost = 0; startNode.hCost = GetDistance(startNode, targetNode); openSet.Add(startNode); while (openSet.Count > 0) { Node currentNode = openSet.RemoveFirst(); closedSet.Add(currentNode); currentNode.isInClosedSet = true; if (currentNode == targetNode) { path = RetracePath(startNode, currentNode); break; } else { foreach (Node neighbourNode in currentNode.neighbours) { if (!neighbourNode.isBlocked && !neighbourNode.isInClosedSet) { int newMovementCost = currentNode.gCost + GetDistance(currentNode, neighbourNode); bool openListContainsNeighbour = openSet.Contains(neighbourNode); if (newMovementCost < neighbourNode.gCost || !openListContainsNeighbour) { neighbourNode.gCost = newMovementCost; neighbourNode.hCost = GetDistance(neighbourNode, targetNode); neighbourNode.prevNode = currentNode; if (!openListContainsNeighbour) { openSet.Add(neighbourNode); } else { openSet.UpdateItem(neighbourNode); } } } } } } ResetClosedSet(closedSet); return(path); }
protected virtual void Update() { node = pathGridManager.GetNodeFromWorldPos(transform.position); }