public Cell CellInDirection(Direction dir) { switch (dir) { case Direction.North: if (y < CellGen.cellsPerSide - 1) { return(CellGen.GetCellAt(x, y + 1)); } break; case Direction.South: if (y > 0) { return(CellGen.GetCellAt(x, y - 1)); } break; case Direction.East: if (x < CellGen.cellsPerSide - 1) { return(CellGen.GetCellAt(x + 1, y)); } break; case Direction.West: if (x > 0) { return(CellGen.GetCellAt(x - 1, y)); } break; default: Debug.LogWarning("Invalid direction " + dir); break; } return(null); }
public static Vector3[] PathTo(Vector3 fromPoint, Vector3 toPoint) { fromPoint.y = toPoint.y = 0; Cell startCell = CellGen.GetCellAt(fromPoint); Cell endCell = CellGen.GetCellAt(toPoint); if (startCell.x < 0 || endCell.y < 0) { Debug.Log("Invalid path start and/or end"); return(null); } // A* setup var evaluated = new List <Cell>(); var toEvaluate = new List <Cell>(); var cameFrom = new Dictionary <Cell, Cell>(); var costTo = new Dictionary <Cell, int>(); var costFrom = new Dictionary <Cell, float>(); var totalCost = new Dictionary <Cell, float>(); toEvaluate.Add(startCell); costTo.Add(startCell, 0); costFrom.Add(startCell, HeuristicDist(startCell, endCell)); totalCost.Add(startCell, costFrom[startCell]); // A* loop while (toEvaluate.Count > 0) { Cell evalPoint = null; float lowestCost = float.MaxValue; foreach (var cell in toEvaluate) // perhaps ove toeval to a heap or something { float newCost = totalCost[cell]; if (newCost < lowestCost) { lowestCost = newCost; evalPoint = cell; } } // if reached dest if (evalPoint == endCell) { var cellPath = PathFrom(cameFrom, evalPoint); var path = new List <Vector3>(); path.Add(fromPoint); for (int i = 1; i < cellPath.Count - 1; i++) { path.Add(cellPath[i].centrePosition); } path.Add(toPoint); path = SmoothPath(path); return(path.ToArray()); } toEvaluate.Remove(evalPoint); evaluated.Add(evalPoint); var neighbours = new List <Cell>(); if (evalPoint.canGoNorth && evalPoint.CellInDirection(Direction.North).room != 0) { neighbours.Add(evalPoint.CellInDirection(Direction.North)); } if (evalPoint.canGoSouth && evalPoint.CellInDirection(Direction.South).room != 0) { neighbours.Add(evalPoint.CellInDirection(Direction.South)); } if (evalPoint.canGoEast && evalPoint.CellInDirection(Direction.East).room != 0) { neighbours.Add(evalPoint.CellInDirection(Direction.East)); } if (evalPoint.canGoWest && evalPoint.CellInDirection(Direction.West).room != 0) { neighbours.Add(evalPoint.CellInDirection(Direction.West)); } foreach (Cell newPoint in neighbours) { if (evaluated.Contains(newPoint)) { continue; } int tentCostTo = costTo[evalPoint] + 1; if (!toEvaluate.Contains(newPoint)) { toEvaluate.Add(newPoint); costTo.Add(newPoint, tentCostTo); costFrom.Add(newPoint, HeuristicDist(newPoint, endCell)); totalCost.Add(newPoint, tentCostTo + costFrom[newPoint]); cameFrom.Add(newPoint, evalPoint); } else if (tentCostTo < costTo[newPoint]) { costTo[newPoint] = tentCostTo; cameFrom[newPoint] = evalPoint; totalCost[newPoint] = tentCostTo + costFrom[newPoint]; } } } Debug.Log("No path found from " + fromPoint + " to " + toPoint); return(null); }