I'm relatively new to Unity, and I wanted to use the Job system for a complex pathfinding algorithm, since it will likely be used alongside multiple instances of NPCs attempting to find a valid route. Just as a test, I ran a single instance:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Mathematics;
using Unity.Collections;
using Unity.Jobs;
using Unity.Burst;
using System.Linq;
using Unity.VisualScripting;
public class Pathfinding : MonoBehaviour {
public List<Vector3> PathList = null;
public static Pathfinding Instance { get; private set; }
public Pathfinding() {
Instance = this;
}
void Start(){
Vector3 startPosition = new Vector3(1, 2);
Vector3 startPosition2 = new Vector3(2, 3);
PathList = FindPath(startPosition, startPosition2);
}
public List<Vector3> FindPath(Vector3 startPosition, Vector3 endPosition){
Debug.Log("Activated");
List<Vector3> pathList = null;
NativeList<int2> paths = new NativeList<int2>(Allocator.Persistent);
// NativeArray<JobHandle> jobHandleArray = new NativeArray<JobHandle>(findPathJobCount, Allocator.TempJob);
FindPathJob findPathJob = new FindPathJob {
startPosition = new int2((int) startPosition.x, (int) startPosition.y),
endPosition = new int2((int) endPosition.x, (int) endPosition.y),
paths = paths // output paths
};
JobHandle jobHandle = findPathJob.Schedule();
jobHandle.Complete();
if(paths.Length != 0){
Debug.Log("paths not empty");
for(int i = paths.Length-1; i >= 0; i--){
int xcoord = paths[i].x;
int ycoord = paths[i].y;
pathList.Add(new Vector3(xcoord, ycoord));
}
}
else{
Debug.Log("paths are empty");
}
paths.Dispose();
// JobHandle.CompleteAll(jobHandleArray);
// jobHandle.Dispose();
return pathList;
}
[BurstCompile]
private struct FindPathJob : IJob {
public int2 startPosition;
public int2 endPosition;
public NativeList<int2> paths;
public void Execute() {
int2 gridSize = new int2(100, 100);
NativeArray<PathNode> pathNodeArray = new NativeArray<PathNode>(gridSize.x * gridSize.y, Allocator.Temp);
// pathfinding algorithm code
if (endNode.cameFromNodeIndex == -1) {
// Didn't find a path!
Debug.Log("Didn't find a path!");
} else {
// Found a path
paths = CalculatePath(pathNodeArray, endNode);
Debug.Log("Found Paths!");
Debug.Log("Paths size: " + paths.Length);
foreach (int2 pathPosition in paths) {
Debug.Log(pathPosition);
}
}
pathNodeArray.Dispose();
neighbourOffsetArray.Dispose();
openList.Dispose();
closedList.Dispose();
}
}
}
The print statement when a path is found in the job prints "Found Job!" and a valid path, but the code calling paths in the FindPath() function instead says "paths are empty". My question is, how do I get paths in FindPath() to update when it is changed in the job?
JobHandle jobHandle = findPathJob.Schedule();and then pause the main thread until it is finished by callingjobHandle.Complete();immediately afterwards. A better pattern is to let the job run in the background and periodically check its status viajobHandle.IsCompletedin subsequentUpdates or in a coroutine. \$\endgroup\$