// Spawns the agent facing towards it's goal tile. public bool Spawn(Tile location) { path = AStarHelper.Calculate(location, Goal, speedPerFrame); if (path == null // TODO: Fix the issue with pathfinding that makes this necessary (without removing the occasional non-optimal paths if possible) || path.OfType <PathfindingMovement>().Sum(pm => Vector3.Distance(pm.Origin.Position, pm.Destination.Position)) > 4 * Vector3.Distance(location.Position, Goal.Position) || path.OfType <PathfindingDelay>().Any(pd => pd.Delay > 50)) { //Debug.LogError(String.Format("Failed to find path from [{0},{1}] to [{2},{3}]!", location.X, location.Z, Goal.X, Goal.Z)); //Debug.DrawLine(location.Position, Goal.Position, Color.red, 5); return(false); } agent = (GameObject)GameObject.Instantiate(model, location.Position, Quaternion.LookRotation(Goal.Position)); ClaimPath(); return(true); }
// Calculate the A* path public static List <IPathAction <T> > Calculate <T>(T start, T goal, float speed) where T : IPathNode <T> { List <T> closedset = new List <T>(); // The set of nodes already evaluated. List <T> openset = new List <T>(); // The set of tentative nodes to be evaluated. openset.Add(start); Dictionary <T, T> cameFrom = new Dictionary <T, T>(); // The map of navigated nodes. Dictionary <T, float> gScore = new Dictionary <T, float>(); gScore[start] = 0.0f; // Cost from start along best known path. Dictionary <T, float> hScore = new Dictionary <T, float>(); hScore[start] = HeuristicCostEstimate(start, goal, speed); Dictionary <T, float> fScore = new Dictionary <T, float>(); fScore[start] = hScore[start]; // Estimated total cost from start to goal through y. while (openset.Count != 0) { T x = LowestScore(openset, fScore); if (x.Equals(goal)) { int time = 0; List <IPathAction <T> > result = new List <IPathAction <T> >(); ReconstructPath(cameFrom, x, default(T), speed, ref result, ref time); return(result); } openset.Remove(x); closedset.Add(x); foreach (T y in x.Connections) { if (AStarHelper.Invalid(y) || closedset.Contains(y)) { continue; } float tentativeGScore = gScore[x] + Distance(x, y, (int)(gScore[x] / speed), speed); bool tentativeIsBetter = false; if (!openset.Contains(y)) { openset.Add(y); tentativeIsBetter = true; } else if (tentativeGScore < gScore[y]) { tentativeIsBetter = true; } if (tentativeIsBetter) { cameFrom[y] = x; gScore[y] = tentativeGScore; hScore[y] = HeuristicCostEstimate(y, goal, speed); fScore[y] = gScore[y] + hScore[y]; } } } return(null); }