using UnityEngine; using System.Collections; using System.Collections.Generic; public class AStar : MonoBehaviour { public int rows = 6; public int cols = 6; public GameObject tile; public GameObject enemy; public static Tile[,] map; public Tile startPos; public Tile endPos; public Heap open; void Start () { map = new Tile[rows, cols]; float startx = -(float)rows / 2f * tile.transform.lossyScale.x; float starty = (float)cols / 2f * tile.transform.lossyScale.y; for (int y = 0; y < cols; y++) { for (int x = 0; x < rows; x++) { map[x, y] = ((GameObject) Instantiate (tile, new Vector2(startx + x * tile.GetComponent().size.x, starty - y * tile.GetComponent().size.x), Quaternion.identity)).GetComponent (); map [x, y].x = x; map [x, y].y = y; } } open = new Heap (rows * cols); enemy = (GameObject)(Instantiate (enemy, map[0, 0].transform.position, Quaternion.identity)); } void FixedUpdate () { if (map[rows - 1, cols - 1].prev != null) { Tile current = map [rows - 1, cols - 1]; while (current.prev != null) { Debug.DrawLine (current.transform.position, current.prev.transform.position, Color.red); current = current.prev; } } } public void BeginPath () { Path (map[0, 0], map[rows - 1, cols - 1]); } void Path (Tile start, Tile finish) { if (start == finish) { return; } open.Add (start); start.goal = 0; start.fitness = EstimateHeuristic (start, finish); while (open.Count != 0) { Tile current = open.RemoveFirst (); current.closed = true; List neighbors = current.GetNeighbors(); for (int i = 0; i < neighbors.Count; i++) { if (neighbors[i].closed) { continue; } float tempGoal = current.goal + DistBetween(current, neighbors[i]) + neighbors[i].weight; if (!open.Contains (neighbors[i])) { neighbors [i].prev = current; neighbors [i].goal = tempGoal; neighbors [i].fitness = neighbors[i].goal + EstimateHeuristic(neighbors[i], finish); open.Add (neighbors [i]); }else if (tempGoal >= neighbors[i].goal) { continue; } } } // PrintPathRetrace (finish); if (finish.prev != null) { enemy.GetComponent ().BeginTraversingPath (CreatePath (finish)); } } float EstimateHeuristic (Tile current, Tile finish) { return Mathf.Abs (current.x - finish.x) + Mathf.Abs (current.y - finish.y); } float DistBetween (Tile current, Tile neighbor) { return Mathf.Pow(current.x - neighbor.x, 2) + Mathf.Pow(current.y - neighbor.y, 2); } void PrintPathRetrace (Tile end) { while (end != null) { Debug.Log (end.x + ", " + end.y); end = end.prev; } } Path CreatePath (Tile finish) { Path path = new Path (); while (finish != null) { path.Push (finish); finish = finish.prev; } return path; } }