Я пытаюсь реализовать алгоритм AStars для своей игры. Суть алгоритма заключаетсяв поиске пути по графу
Граф я создал, но теперь я не могу подключить сам алгоритм
Это класс Astars. Есть ещё класс Node, но там ничего такого, просто конструктор и набор параметров для каждой из вершин
public class Astar
{
List<List<Node>> Grid; //нужно для алгоритма. Это просто разметка карты на вершины графа
int GridRows
{
get
{
return Grid[0].Count;
}
}
int GridCols
{
get
{
return Grid.Count;
}
}
public Astar(List<List<Node>> grid) //конструктор
{
Grid = grid;
}
public Stack<Node> FindPath(Vector2 Start, Vector2 End) //сам алгоритм поиска пути
{
Node start = new Node(new Vector2((int)(Start.x/Node.NODE_SIZE), (int) (Start.y/Node.NODE_SIZE)), true);
Node end = new Node(new Vector2((int)(End.x / Node.NODE_SIZE), (int)(End.y / Node.NODE_SIZE)), true);
Stack<Node> Path = new Stack<Node>();
List<Node> OpenList = new List<Node>();
List<Node> ClosedList = new List<Node>();
List<Node> adjacencies;
Node current = start;
// add start node to Open List
OpenList.Add(start);
while(OpenList.Count != 0 && !ClosedList.Exists(x => x.Position == end.Position))
{
current = OpenList[0];
OpenList.Remove(current);
ClosedList.Add(current);
adjacencies = GetAdjacentNodes(current);
foreach(Node n in adjacencies)
{
if (!ClosedList.Contains(n) && n.Walkable)
{
if (!OpenList.Contains(n))
{
n.Parent = current;
n.DistanceToTarget = Math.Abs(n.Position.x - end.Position.x) + Math.Abs(n.Position.y - end.Position.y);
n.Cost = n.Weight + n.Parent.Cost;
OpenList.Add(n);
OpenList = OpenList.OrderBy(node => node.F).ToList<Node>();
}
}
}
}
// construct path, if end was not closed return null
if(!ClosedList.Exists(x => x.Position == end.Position))
{
return null;
}
// if all good, return path
Node temp = ClosedList[ClosedList.IndexOf(current)];
if (temp == null) return null;
do
{
Path.Push(temp);
temp = temp.Parent;
} while (temp != start && temp != null) ;
return Path;
}
private List<Node> GetAdjacentNodes(Node n)
{
List<Node> temp = new List<Node>();
int row = (int)n.Position.y;
int col = (int)n.Position.x;
if(row + 1 < GridRows)
{
temp.Add(Grid[col][row + 1]);
}
if(row - 1 >= 0)
{
temp.Add(Grid[col][row - 1]);
}
if(col - 1 >= 0)
{
temp.Add(Grid[col - 1][row]);
}
if(col + 1 < GridCols)
{
temp.Add(Grid[col + 1][row]);
}
return temp;
}
}
И есть скрипт для моего юнита
public class warrior : MonoBehaviour
{
Astar astar; //создаю объект класса Astar, чтобы потом вызывать FindPath
private navigationSquare square; //это нужно для нахождения конечной точки
public GameObject grid; //на этом объекте висит скрипт navigationSquare
Stack<Node> path = new Stack<Node>(); //стек с путем, который вернет функция astar.FindPath(...);
void Start()
{
square = grid.GetComponent<navigationSquare>(); //получаю доступ к скрипту
Debug.Log(square.end.x);
astar = new Astar(makeGrid.getGraph()); //инициализирую объект при помощи конструктора
//makeGrid.getGraph() вернет List<List<Node>> карту графов
}
// Update is called once per frame
void Update()
{
if(square.canGo == true){
Vector2 pos_start = new Vector2(transform.position.x, transform.position.y); //начальная позиция юнита
Vector2 pos_end = new Vector2(square.end.x, square.end.y); //и место, куда он должен придти
path = astar.FindPath(pos_start, pos_end);
printPath(); //её реализация не важна
}
}
}
в итоге я получаю вот такой error 
Я так понимаю, что у меня ошибка в том, что я как-то неправильно создаю объект класса Astar или что я неправильно вызываю его методы
Уже несколько дней ломаю голову над этими NullReferenceException....
Научите неразумного, добрые люди(
102 строка adjacencies = GetAdjacentNodes(current);
145 строка if(row + 1 < GridRows)
29 строка path = astar.FindPath(pos_start, pos_end);
OpenList.OrderBy- здесь с помощьюLinqвы пересоздаете список, это медленно и кушает память, попробуйте вместо этого использовать методList.Sort(). Это не решит вашу проблему, но улучшит производительность кода. По поводуnull- все просто, методGetAdjacentNodesполучаетnullна вход в качестве аргумента, и при попытке обратиться к этомуnull(n.Position), вы получаете искомое исключение. – aepot Feb 11 '21 at 09:01GridRows, ну тогда возможно скрипт выполняется до того как вы создали поле, попробуйте защитить геттерыreturn Grid[0].Count;замените наreturn GridCols > 0 ? Grid[0]?.Count ?? 0 : 0;, аreturn Grid.Count;наreturn Grid?.Count ?? 0;– aepot Feb 11 '21 at 09:10