public static PathInfo GetStraightPath(Unit unit, PathSquare start, PathSquare end) { HashSet <PathSquare> closedSet = new HashSet <PathSquare>(); ResetPathSquare(); bool reachedGoal = false; var direction = (end.pos.ToVector() - start.pos.ToVector()).normalized; var current = start; while (current != null) { if (current == end) { //return PathInfo.GenerateWaypoints(start, current); reachedGoal = true; } closedSet.Add(current); var next = current.pos.ToVector() + direction; PathSquareNeighbourInfo nextNeighbour; if (current.neighbours.TryGetValue(next.ConvertToIPosition(), out nextNeighbour)) { if (!closedSet.Contains(nextNeighbour.neighbour)) { if (nextNeighbour.neighbour == end || CanWalkToSquare(unit, nextNeighbour)) { nextNeighbour.neighbour.parent = current; current = nextNeighbour.neighbour; continue; } } } break; } if (reachedGoal) { return(PathInfo.GenerateWaypoints(start, current)); } return(null); }
public static PathInfo GetShortestPath(Unit unit, PathSquare start, PathSquare end) { HashSet <PathSquare> closedSet = new HashSet <PathSquare>(); HashSet <PathSquare> openSet = new HashSet <PathSquare>(); PathSquare closestSquare = null; double closestDistance = 9999; openSet.Add(start); ResetPathSquare(); start.gScore = 0; start.fScore = start.Distance(end); double bestRouteDist = start.Distance(end); while (openSet.Count > 0) { var current = openSet.OrderBy(n => n.fScore).FirstOrDefault(); if (current == end) { return(PathInfo.GenerateWaypoints(start, current)); } openSet.Remove(current); closedSet.Add(current); foreach (var pair in current.neighbours) { var neighbourInfo = pair.Value; var neighbour = neighbourInfo.neighbour; var distance = neighbourInfo.distance; if (closedSet.Contains(neighbour)) { continue; } if (!CanWalkToSquare(unit, neighbourInfo)) { continue; } var alternativeDistance = current.gScore + distance; /*if(alternativeDistance > bestRouteDist * 2) * { * continue; //stop searching for route that's longer than 2x the optimal path * }*/ if (!openSet.Contains(neighbour)) { openSet.Add(neighbour); } else if (alternativeDistance >= neighbour.gScore) { continue; } var estimatedDistance = neighbour.Distance(end); neighbour.parent = current; neighbour.gScore = alternativeDistance; neighbour.fScore = alternativeDistance + estimatedDistance; if (closestDistance > estimatedDistance) { closestSquare = neighbour; closestDistance = estimatedDistance; } } } if (closestSquare == null) { return(null); } if (closestSquare.Distance(end) < start.Distance(end)) { var path = PathInfo.GenerateWaypoints(start, closestSquare); path.reachable = false; return(path); } else { return(null); } }