As the title suggests I have been following the wonderful series of tutorials dealing with pathfinding made by Sebastian Lague.
My problem is that the code is meant to be working immediately after launching the scene. It works fine and all, but I simply cannot seem to make it run on a condition, be it a mouse click or any other sort of trigger. Did somebody manage to do it? If so can you please explain please?
In the specific, the problems start to arise going from the 4th to the 5th video, in which mutliple units are taken into account and therefore a new script handling the multiple requests to find paths is added.
The main method in the pathfinding script is this (let's call it pathfinding):
public void StartFindPath(Vector3 startPos, Vector3 targetPos) {
StartCoroutine(FindPath(startPos, targetPos));
}
And the called coroutine is something like:
IEnumerator FindPath(Vector3 startPosition, Vector3 targetPosition) {
Stopwatch sw = new Stopwatch();
sw.Start();
Vector3[] wayPoints = new Vector3[0];
bool pathSuccess = false;
Node1 startNode = grid.NodeFromWorldPoint(startPosition);
Node1 targetNode = grid.NodeFromWorldPoint(targetPosition);
if (startNode.walkable && targetNode.walkable) {
//<Update open & closed lists>
while (openSet.Count > 0) {
Node1 currentNode = openSet.RemoveFirst();
closedSet.Add(currentNode);
if (currentNode == targetNode) {
sw.Stop();
pathSuccess = true;
RetracePath(startNode, targetNode);
break;
}
foreach (Node1 neighbor in grid.GetNeighbors(currentNode)) {
// Retrieve f cost and find a path
}
}
}
yield return null;
if (pathSuccess) {
wayPoints = RetracePath(startNode, targetNode);
}
requestManager.FinishedProcessingPath(wayPoints,pathSuccess);
}
The request manager script (requestManager) instead is this:
public class PathRequestManager : MonoBehaviour {
Queue<PathRequest> pathRequestQueue = new Queue<PathRequest>();
PathRequest currentPathRequest;
static PathRequestManager instance;
PathFinding pathFinding;
bool isProcessingPath;
private void Awake() {
instance = this;
pathFinding = GetComponent<PathFinding>();
}
public static void RequestPath(Vector3 pathStart, Vector3 pathEnd, Action<Vector3[], bool> callback) {
PathRequest newRequest = new PathRequest(pathStart, pathEnd, callback);
instance.pathRequestQueue.Enqueue(newRequest);
instance.TryProcessNext();
}
void TryProcessNext() {
if (!isProcessingPath && pathRequestQueue.Count > 0) {
currentPathRequest = pathRequestQueue.Dequeue();
isProcessingPath = true;
pathFinding.StartFindPath(currentPathRequest.pathStart, currentPathRequest.pathEnd);
}
}
public void FinishedProcessingPath(Vector3[] path, bool success) {
currentPathRequest.callback(path, success);
isProcessingPath = false;
TryProcessNext();
}
struct PathRequest {
public Vector3 pathStart;
public Vector3 pathEnd;
public Action<Vector3[], bool> callback;
public PathRequest(Vector3 _start, Vector3 _end, Action<Vector3[], bool> _callback) {
pathStart = _start;
pathEnd = _end;
callback = _callback;
}
}
}
Finally, each unit object is provided with a "unit" script in which there is this corouting used to follow the path retrieved from the pathfinding script:
IEnumerator FollowPath() {
Vector3 currentWayPoint = path[0];
while (true) {
if (transform.position == currentWayPoint) {
targetIndex++;
if (targetIndex >= path.Length) {
yield break;
}
currentWayPoint = path[targetIndex];
}
transform.position = Vector2.MoveTowards(transform.position, currentWayPoint, speed * Time.deltaTime);
yield return null;
}
}
I tried at first to wrap the the StartFindPath()
in pathfinding in an if statement made true upon pressing a button, but it did not work, so i tried to do the same only with the StartCoroutine
line, but I ended up with the same result. I thought about doing it for the FollowPath
method in the unit script, but it is called in this method:
public void OnPathFound(Vector3[] newPath, bool pathSuccessful) {
if (pathSuccessful) {
path = newPath;
StopCoroutine(FollowPath());
StartCoroutine(FollowPath());
}
}
And I am not sure if it is the most suitable way. I tried to limit as much as possible the amount of code in the question, but if you need more I will add the rest of the scripts (FYI there are also a script in which the nodes features are defined, one to create the grid and one to define the heap data structure).