Hello, i am making a basic a* algorithm in unity and my code is below. when i start my game the whole unity editor crashes and i have to start it up again. nothing shows up in the console it just crashes and I don’t know why this is happening?
even if i have an out of bounds or code error it shouldn’t crash the whole editor right?
using UnityEngine;
using System.Collections.Generic;
public class Pathfinding : MonoBehaviour
{
public Transform seeker;
public Transform target;
Grid grid;
void Awake(){
grid = GetComponent<Grid>();
}
void Start(){
FindPath(seeker.position, target.position);
}
void FindPath(Vector3 startPos, Vector3 targetPos){
Node startNode = grid.WorldPositionToNode(startPos);
Node targetNode = grid.WorldPositionToNode(targetPos);
List<Node> openSet = new List<Node>();
HashSet<Node> closedSet = new HashSet<Node>();
openSet.Add(startNode);
while(openSet.Count > 0){
Node currentNode = openSet[0];
for(int i = 1; i < openSet.Count; i++){
if(openSet[i].fCost < currentNode.fCost || (openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost)){
currentNode = openSet[i];
}
}
openSet.Remove(currentNode);
closedSet.Add(currentNode);
if(currentNode == targetNode){
RetracePath(startNode, targetNode);
return;
}
foreach (Node neighbor in grid.FindNeighborFromNode(currentNode)){
if(!neighbor.walkable || closedSet.Contains(neighbor)) continue;
int newMovementCostToNeighbor = currentNode.gCost + GetDistance(currentNode, neighbor);
if(newMovementCostToNeighbor < neighbor.gCost || !openSet.Contains(neighbor)){
neighbor.gCost = newMovementCostToNeighbor;
neighbor.hCost = GetDistance(neighbor, targetNode);
neighbor.Parent = currentNode;
if(!openSet.Contains(neighbor)){
openSet.Add(neighbor);
}
}
}
}
}
void RetracePath(Node startNode, Node endNode){
List<Node> path = new();
Node currentNode = endNode;
while(currentNode != startNode){
path.Add(currentNode);
currentNode = currentNode.Parent;
}
path.Reverse();
grid.path = path;
}
int GetDistance(Node nodeA, Node nodeB){
int x = nodeA.gridX - nodeB.gridX;
int y = nodeA.gridY - nodeB.gridY;
if(y > x){
return 14*y + 10*(x-y);
}
return 14*x + 10*(y-x);
}
}
using UnityEngine;
using System.Collections.Generic;
public class Grid : MonoBehaviour
{
[SerializeField]
private LayerMask unwalkableMask;
[SerializeField]
private Vector2 gridWorldSize;
[SerializeField]
private float nodeRadius;
Node[,] grid;
private float nodeDiameter;
private int gridSizeX, gridSizeY;
public List<Node> path;
void OnDrawGizmos(){
Gizmos.DrawWireCube(transform.position, new Vector3(gridWorldSize.x, 1, gridWorldSize.y));
if(grid != null){
foreach(Node n in grid){
Gizmos.color = n.walkable ? Color.green : Color.black;
if(path != null){
if(path.Contains(n)){
Gizmos.color = Color.blue;
}
}
Gizmos.DrawCube(n.worldPosition,Vector3.one * (nodeDiameter - .1f));
}
}
}
void Awake(){
nodeDiameter = nodeRadius*2;
gridSizeX = Mathf.RoundToInt(gridWorldSize.x / nodeDiameter);
gridSizeY = Mathf.RoundToInt(gridWorldSize.y/nodeDiameter);
CreateGrid();
}
void CreateGrid(){
grid = new Node[gridSizeX, gridSizeY];
Vector3 worldBottomLeft = transform.position - Vector3.right * gridWorldSize.x/2 - Vector3.forward * gridWorldSize.y/2;
for(int x = 0; x < gridSizeX; x++){
for(int y = 0; y < gridSizeY; y++){
Vector3 worldPoint = worldBottomLeft + Vector3.right * (x * nodeDiameter + nodeRadius) + Vector3.forward * (y * nodeDiameter + nodeRadius);
bool walkable = !Physics.CheckSphere(worldPoint, nodeRadius, unwalkableMask);
grid[x,y] = new Node(walkable, worldPoint, x, y);
}
}
}
public List<Node> FindNeighborFromNode(Node node){
List<Node> neighbors = new();
for(int x = -1; x < 2; x++){
for(int y = -1; y < 2; y++){
if(x==0 && y==0) continue;
int currentGridX = node.gridX + x;
int currentGridY = node.gridY + y;
//bounds check
if(currentGridX < gridSizeX && currentGridX >= 0 && currentGridY >= 0 && currentGridY < gridSizeY){
neighbors.Add(grid[currentGridX,currentGridY]);
}
}
}
return neighbors;
}
public Node WorldPositionToNode(Vector3 worldPosition){
Vector3 worldBottomLeft = transform.position - Vector3.right * gridWorldSize.x/2 - Vector3.forward * gridWorldSize.y/2;
float percentX = (worldPosition.x - worldBottomLeft.x) / gridWorldSize.x;
float percentY = (worldPosition.z - worldBottomLeft.z) / gridWorldSize.y;
percentX = Mathf.Clamp01(percentX);
percentY = Mathf.Clamp01(percentY);
int x = Mathf.RoundToInt((gridSizeX - 1) * percentX);
int y = Mathf.RoundToInt((gridSizeY - 1) * percentY);
return grid[x, y];
}
}
using UnityEngine;
public class Node
{
public bool walkable;
public Vector3 worldPosition;
public int gridX;
public int gridY;
public int gCost;
public int hCost;
public Node Parent;
public Node(bool _walkable, Vector3 _worldPos, int _gridX, int _gridY){
walkable = _walkable;
worldPosition = _worldPos;
gridX = _gridX;
gridY= _gridY;
}
public int fCost{
get {
return gCost + fCost;
}
}
}