131 lines
5.1 KiB
Plaintext
131 lines
5.1 KiB
Plaintext
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<cellData>().x = x;
|
|
cell.GetComponent<cellData>().y = y;
|
|
cell.transform.parent = cellsParent;
|
|
|
|
//isObstacle?
|
|
cell.GetComponent<cellData>().setObstacle(Physics2D.BoxCast(cell.transform.position, cell.transform.localScale/2f, 0 ,Vector2.zero));
|
|
//cell.GetComponent<cellData>().setObstacle(Physics2D.CircleCast(cellSpawnPos,cellSize /2f,Vector2.zero));
|
|
|
|
//cells.Add(cell.GetComponent<cellData>());
|
|
cells[x,y] = cell.GetComponent<cellData>();
|
|
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<SpriteRenderer>().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<SpriteRenderer>().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();
|
|
}
|
|
}
|
|
}
|