private unsafe void AStarSolver(int2 start, int2 goal, int index, Entity agent) { // data containers sliced from shared data structures var openSet = OpenSet.Slice(index * _maxLength, _maxLength); var closedSet = ClosedSet.Slice(index * _maxLength, _maxLength); var G_Costs = Gcosts.Slice(index * _maxLength, _maxLength); var neighbours = new NativeList <int2>(8, Allocator.TempJob); // reset of data containers openSet.Clear(); void *buffer = closedSet.GetUnsafePtr(); UnsafeUtility.MemClear(buffer, (long)closedSet.Length * UnsafeUtility.SizeOf <MinHeapNode>()); buffer = G_Costs.GetUnsafePtr(); UnsafeUtility.MemClear(buffer, (long)G_Costs.Length * UnsafeUtility.SizeOf <int>()); var startNode = new MinHeapNode(GridGeneratorSystem.grid[start.x, start.y], start); openSet.Push(startNode); while (openSet.HasNext()) { var currentNode = openSet.Pop(); currentNode.IsClosed = 1; closedSet[GetIndex(currentNode.Position)] = currentNode; // if goal node is reached then the path is created and assigned to the agent entity if (currentNode.Position.x == goal.x && currentNode.Position.y == goal.y) { var path = new NativeList <int2>(Allocator.TempJob); var current = currentNode; while (current.ParentPosition.x != -1) { path.Add(current.Position); current = closedSet[GetIndex(current.ParentPosition)]; } path.Add(current.Position); CreatePath(agent, ref path); path.Dispose(); break; } GetNeighbours(currentNode.Position, ref neighbours); for (int i = 0; i < neighbours.Length; i++) { var neighbourEntity = GridGeneratorSystem.grid[neighbours[i].x, neighbours[i].y]; // if current neighbour is in closed list or is unwalkable then skip to next if (closedSet[GetIndex(neighbours[i])].IsClosed == 1 || !Walkables[neighbourEntity].Value) { continue; } int costSoFar = G_Costs[GetIndex(currentNode.Position)] + Heuristics.OctileDistance(currentNode.Position, neighbours[i]); if (G_Costs[GetIndex(neighbours[i])] == 0 || costSoFar < G_Costs[GetIndex(neighbours[i])]) { // update costs int h = Heuristics.OctileDistance(neighbours[i], goal); int f = costSoFar + h; G_Costs[GetIndex(neighbours[i])] = costSoFar; var node = new MinHeapNode(neighbourEntity, neighbours[i], currentNode.Position, f, h); // if openSet contains node => update node openSet.IfContainsRemove(node.NodeEntity); openSet.Push(node); } } } neighbours.Dispose(); }