I have been wanting to learn how to do pathfinding for awhile and decided to dive it but I need help? When I put everything in to this while look it crashes unity. Any input would be nice and how to improve the current code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AStar : MonoBehaviour
{
private Grid grid;
public Node start;
public Node end;
public Node cNode;
// Start is called before the first frame update
void Start()
{
grid = GetComponent<Grid>();
}
// Update is called once per frame
void Update()
{
Star();
}
void Star()
{
Node startNode = grid.grid[0, 0];
Node endNode = grid.grid[4, 5];
start = startNode;
end = endNode;
List<Node> openSet = new List<Node>();
HashSet<Node> closedSet = new HashSet<Node>();
openSet.Add(startNode);
Node currentNode = openSet[0];
cNode = currentNode;
while (openSet.Count > 0)
{
for (int i = 0; i < openSet.Count; i++)
{
if (openSet[i].fCost < currentNode.fCost)
{
currentNode = openSet[i];
}
}
openSet.Remove(currentNode);
closedSet.Add(currentNode);
if (currentNode == endNode)
{
RetracePath(startNode, endNode);
return;
}
foreach (Node n in currentNode.neibou)
{
if (n.walkAble == false || closedSet.Contains(n))
{
continue;
}
int newCostToNeighbour = currentNode.gCost + GetDistance(currentNode, n);
if (newCostToNeighbour < n.gCost || !openSet.Contains(n))
{
n.gCost = newCostToNeighbour;
n.hCost = GetDistance(n, endNode);
n.parent = currentNode;
if (!openSet.Contains(n))
openSet.Add(n);
}
}
}
}
void RetracePath(Node startNode, Node endNode)
{
List<Node> path = new List<Node>();
Node currentNode = endNode;
while (currentNode != startNode)
{
path.Add(currentNode);
currentNode = currentNode.parent;
}
path.Reverse();
grid.path = path;
}
int GetDistance(Node nodeA, Node nodeB)
{
int dstX = Mathf.Abs(nodeA.gridX - nodeB.gridX);
int dstY = Mathf.Abs(nodeA.gridY - nodeB.gridY);
if (dstX > dstY)
return 14 * dstY + 10 * (dstX - dstY);
return 14 * dstX + 10 * (dstY - dstX);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class Grid : MonoBehaviour
{
public GameObject holder;
public GameObject nodePrefab;
public List<Node> nodes = new List<Node>();
public int X;
public int Y;
public Node[,] grid;
// Start is called before the first frame update
void Start()
{
CreateGrid();
wall();
TiletoTile();
}
private void Update()
{
if (grid != null)
{
foreach (Node n in grid)
{
n.gameObject.GetComponent<SpriteRenderer>().color = (n.walkAble) ? Color.white : Color.red;
if (path != null)
if (path.Contains(n))
n.gameObject.GetComponent<SpriteRenderer>().color = Color.black;
}
}
}
public void CreateGrid()
{
grid = new Node[X, Y];
// grid[X, Y].walkAble = true;
for (int x = 0; x < X; x++)
{
for (int y = 0; y < Y; y++)
{
Node newNode = Instantiate(nodePrefab, transform.position, Quaternion.identity).GetComponent<Node>();
newNode.transform.position = new Vector2(x, y);
newNode.transform.parent = holder.transform;
newNode.walkAble = true;
grid[x, y] = newNode;
//Vector2 worldPoint = new Vector2(x, y);
//Node newNode = Instantiate(nodePrefab, transform.position, Quaternion.identity).GetComponent<Node>();
//newNode.transform.parent = holder.transform;
//newNode.transform.position = new Vector2(x, y);
//nodes.Add(newNode);
//grid[x, y] = new Node(x, y,worldPoint);
}
}
}
void wall()
{
grid[3, 2].walkAble = false;
grid[4, 5].walkAble = false;
}
public void Ne(Node node)
{
for (int x = 0; x < X; x++)
{
for (int y = 0; y < Y; y++)
{
if (x - 1 >= 0 && grid[x - 1, y].walkAble)
{
grid[x, y].neibou.Add(grid[x - 1, y]);
}
if (x + 1 < Y && grid[x + 1, y].walkAble)
{
grid[x, y].neibou.Add(grid[x + 1, y]);
}
if (y - 1 >= 0 && grid[x, y - 1].walkAble)
{
grid[x, y].neibou.Add(grid[x, y - 1]);
}
if (y + 1 < X && grid[x, y + 1].walkAble)
{
grid[x, y].neibou.Add(grid[x, y + 1]);
}
}
}
}
void TiletoTile()
{
for (int x = 0; x < X; x++)
{
for (int y = 0; y < Y; y++)
{
if (x - 1 >= 0 &&grid[x -1,y].walkAble)
{
grid[x, y].neibou.Add(grid[x - 1, y]);
}
if (x + 1 < Y && grid[x +1, y].walkAble)
{
grid[x, y].neibou.Add(grid[x + 1, y]);
}
if (y - 1 >= 0 && grid[x, y -1].walkAble)
{
grid[x, y].neibou.Add(grid[x, y - 1]);
}
if (y + 1 < X && grid[x, y+1].walkAble)
{
grid[x, y].neibou.Add(grid[x, y + 1]);
}
}
}
}
public List<Node> GetNeighbours(Node node)
{
List<Node> neightbours = new List<Node>();
for (int x = -1; x <= 1; x++)
{
for (int y = -1; y <=1; y++)
{
if(x == 0 && y == 0)
continue;
int checkX = node.gridX + x;
int checkY = node.gridY + y;
if(checkX >= 0 && checkX < X && checkY >= 0 && checkY < Y)
{
//node.neibou.Add(grid[checkX, checkY]);
neightbours.Add(grid[checkX, checkY]);
}
}
}
return neightbours;
}
public Node NodeFromWorldPoint(Vector3 worldPosition)
{
float percentX = (worldPosition.x + X/ 2) / X;
float percentY = (worldPosition.z + Y / 2) / Y;
percentX = Mathf.Clamp01(percentX);
percentY = Mathf.Clamp01(percentY);
int x = Mathf.RoundToInt((X - 1) * percentX);
int y = Mathf.RoundToInt((Y - 1) * percentY);
return grid[x, y];
}
public List<Node> path;
//void OnDrawGizmos()
//{
// Gizmos.DrawWireCube(transform.position, new Vector3(X, 1, Y));
// if (grid != null)
// {
// foreach (Node n in grid)
// {
// n.gameObject.GetComponent<SpriteRenderer>().color = (n.walkAble) ? Color.white : Color.red;
// if (path != null)
// if (path.Contains(n))
// n.gameObject.GetComponent<SpriteRenderer>().color = Color.black;
// Gizmos.DrawCube(n.worldPosition, Vector3.one * (nodeDiameter - .1f));
// }
// }
//}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Node : MonoBehaviour
{
public bool walkAble;
public Vector2 worldPosition;
public int gridX;
public int gridY;
public int gCost;
public int hCost;
public Node parent;
public List<Node> neibou = new List<Node>();
public Node(int _gridX,int _gridY/*,Vector2 _worldPos*/)
{
//worldPosition = _worldPos;
gridX = _gridX;
gridY = _gridY;
}
public int fCost
{
get
{
return gCost + hCost;
}
}
}