using System.Collections; using System.Collections.Generic; using UnityEngine; public class astar : MonoBehaviour { [Header("Grid Information")] public float width; public float height; public Color gridBoundsVisualizeColor = Color.red; public GameObject cellGameObject; public Transform cellsParent; public cellData[,] cells; public Vector2Int targetCellId; public Vector2Int startCellId; void Start() { StartCoroutine(generateCells()); } IEnumerator generateCells(){ //Generate cells in grid float cellSize = cellGameObject.transform.localScale.x; Vector2 cellStartPosition = new Vector2( transform.position.x - width /2f, transform.position.y - height /2f) + new Vector2(cellSize/2f, cellSize/2f); int horizontalCellCount = (int)(width / cellSize); int verticalCellCount = (int)(height / cellSize); cells = new cellData[horizontalCellCount,verticalCellCount]; for(int x= 0; x < horizontalCellCount; x++){ for(int y = 0; y < verticalCellCount; y++){ Vector2 cellSpawnPos = cellStartPosition + new Vector2(cellSize * x, cellSize *y ); GameObject cell = Instantiate(cellGameObject, cellSpawnPos , Quaternion.identity); cell.GetComponent().x = x; cell.GetComponent().y = y; cell.transform.parent = cellsParent; //isObstacle? cell.GetComponent().setObstacle(Physics2D.BoxCast(cell.transform.position, cell.transform.localScale/2f, 0 ,Vector2.zero)); //cell.GetComponent().setObstacle(Physics2D.CircleCast(cellSpawnPos,cellSize /2f,Vector2.zero)); //cells.Add(cell.GetComponent()); cells[x,y] = cell.GetComponent(); yield return new WaitForSeconds(0.001f); } } } // Update is called once per frame Coroutine calculator = null; void Update() { if(Input.GetKeyDown(KeyCode.E)){ Vector2 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); Vector2Int closestCellId = getClosestCell(worldPos); if(startCellId.magnitude >=0){cells[startCellId.x,startCellId.y].setObstacle();} startCellId = closestCellId; cells[startCellId.x, startCellId.y].GetComponent().color = Color.red; }else if(Input.GetKeyDown(KeyCode.F)){ Vector2 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); if(targetCellId.magnitude >=0){cells[targetCellId.x,targetCellId.y].setObstacle();} Vector2Int closestCell = getClosestCell(worldPos); targetCellId = closestCell; cells[targetCellId.x, targetCellId.y].GetComponent().color = Color.blue; }else if(Input.GetKeyDown(KeyCode.Return)){ if(calculator != null){StopCoroutine(calculator); resetCellsCost();} Debug.Log("Starting calculation"); calculator = StartCoroutine(Calculate()); } } public Vector2Int getClosestCell(Vector2 worldPos){ float minDist = Mathf.Infinity; cellData closestCell = null; foreach(cellData cell in cells){ if(cell.isObstacle){continue;} float DistToCell = Vector3.Distance(worldPos, cell.transform.position); if(DistToCell < minDist){ minDist = DistToCell; closestCell = cell; } } return closestCell; } void OnDrawGizmos(){ //Gizmos.Color = gridBoundsVisualizeColor; Gizmos.color = gridBoundsVisualizeColor; Gizmos.DrawWireCube(transform.position, new Vector3(width, height, 0)); } IEnumerator Calculate(){ bool foundPath = false; Vector2Int closeCellId = startCellId; while(!foundPath){ calculateCellCost(cells[closeCellId.x,closeCellId.y]); for(int x = -1; x <= 1; x++){ for(int y=-1; y <= 1; y++){ int targetX = closeCellId.x +x; int targetY = closeCellId.y +y; if(cells.GetLength(0) < targetX || targetX < 0 || targetY < 0 || cells.GetLength(1) < targetY){continue;} calculateCellCost(cells[targetX,targetY]); } } // cellsToCalculate.Remove(cell); yield return new WaitForSeconds(0.01f); } } void calculateCellCost(cellData cell){ if(cell.fCost==0){return;} float hCost = Vector2.Distance(cell.transform.position, cells[targetCellId.x, targetCellId.y].transform.position); float gCost = Vector2.Distance(cell.transform.position, cells[startCellId.x, startCellId.y].transform.position); float fCost = hCost + gCost; cell.setCellCost(gCost, hCost, fCost); } public void resetCellsCost(){ foreach(cellData cell in cells){ cell.resetCost(); } } }