Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public float2[,] FlowField(MapCell goal, Squad squad = null)
- {
- #if UNITY_EDITOR
- UnityEngine.Profiling.Profiler.BeginSample("FlowField");
- #endif
- // reset costs
- for (int x = 0; x < width; x++)
- {
- for (int y = 0; y < height; y++)
- {
- MapCell cell = grid.grid_cells[x, y];
- cell.cost = 0;
- result[x, y] = 0;
- }
- }
- // result directions
- // open cells
- List<MapCell> open = new List<MapCell>();
- // start dijkstra
- open.Add(goal);
- goal.cost = 0;
- // if there is a squad, only process dijkstra until we reach each squad pawn
- List<Pawn> to_process = null;
- List<int2> coords_to_process = new List<int2>();
- if(squad != null)
- {
- to_process = new List<Pawn>();
- for(int i = 0; i < squad.pawns.Count; i++)
- {
- to_process.Add(squad.pawns[i]);
- }
- }
- while(open.Count > 0)
- {
- MapCell cell = open[0];
- coords_to_process.Add(cell.coords);
- open.RemoveAt(0);
- var neighbours = grid.GetNeighbours(cell);
- for (var i = 0; i < neighbours.Count; i++)
- {
- MapCell n = neighbours[i];
- if(n == null)
- {
- continue;
- }
- if (!open.Contains(n) && n.cost == 0)
- {
- n.cost = cell.cost + n.weight;
- open.Add(n);
- }
- }
- // early break in case we've reached every pawn, no point in going further
- if(to_process != null)
- {
- for (int j = to_process.Count - 1; j >= 0; j--)
- {
- if (cell.pawns.Contains(to_process[j]))
- {
- to_process.RemoveAt(j);
- }
- }
- if (to_process.Count == 0)
- {
- break;
- }
- }
- }
- // after dijkstra create flow field
- for (int j = 0; j < coords_to_process.Count; j++)
- {
- int2 coords = coords_to_process[j];
- MapCell cell = grid.grid_cells[coords.x, coords.y];
- var neighbours = grid.GetNeighbours(cell);
- //Go through all neighbours and find the one with the lowest distance
- MapCell min = null;
- float minDist = 0;
- for (var i = 0; i < neighbours.Count; i++)
- {
- MapCell n = neighbours[i];
- var dist = n.cost - cell.cost;
- if (dist < minDist)
- {
- min = n;
- minDist = dist;
- }
- }
- //If we found a valid neighbour, point in its direction
- if (min != null)
- {
- result[coords.x, coords.y] = math.normalize(min.pos - cell.pos);
- }
- }
- #if UNITY_EDITOR
- UnityEngine.Profiling.Profiler.EndSample();
- #endif
- return result;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement