Canceled path because a new one was requested

Hi !

I’m a beginner user of the A* Library. I tried to compute a A* algorithm once a second on multiple targets -zombies chasing humans =)
What I get after a few moment is the message “Canceled path because a new one was requested”. However, I wrote a script that can only call once at a time the A* API. So does that mean it can only be called once at the same time globally ?

Here is my code:
`using System.Collections;
using System;
using System.Threading;
using UnityEngine;
using Pathfinding;

public class ZombieAI : MonoBehaviour {

//A*
private Seeker seeker;
CharacterController cc;
Path currentPath;

float astarInterval = 1f;
float changePathDistance = 20f;

int currentPathIndex;
float lastAstarTime;
float currentPathLength;
int survivorIndex;

public GameObject target = null;
public GameObject[] survivors;

float speed = 100f;

//initialisation
public void Start () {
	
    seeker = GetComponent<Seeker>();
    cc = GetComponent<CharacterController>();
	
}

	
//path update (target is unchanged)
public void OnPathComplete (Path p) {
	
//We got our path back
if (p.error) {
    Debug.Log(p.error);
} else {
    //Yey, now we can get a Vector3 representation of the path
    //from p.vectorPath

		currentPathIndex = 0;
		currentPath = p;
	}
}

//returns an evaluation of the length of a path, for comparison with others
public float getPathLength(Path p){
	float result = 0f;
	foreach(Vector3 i in p.vectorPath){
		result+=i.sqrMagnitude;
	}
	
	return result;
}

public void Update(){
	
	if(target != null){
		
	//path recompute
	if(Time.time - lastAstarTime > astarInterval){
		lastAstarTime = Time.time;

		seeker.StartPath (transform.position, target.transform.position, OnPathComplete);
	}
	
	//movement 
	if(currentPath != null && currentPathIndex < currentPath.vectorPath.Count){
		Vector3 dir =  currentPath.vectorPath[currentPathIndex] - transform.position;
		
		if(dir.magnitude < changePathDistance && currentPathIndex < currentPath.vectorPath.Count){

			dir = transform.position - currentPath.vectorPath[++currentPathIndex];
		}
		
		cc.Move(speed * Time.deltaTime * dir.normalized);
	}
	
	//eating range
	if((transform.position - target.transform.position).magnitude < 100f)
	{
		Destroy (target);
		
	}
		
	}
	
	else{
		findTarget();
	}
	
}

public void findTarget(){
		
	//first call
	if(survivorIndex == 0){
		survivors = GameObject.FindGameObjectsWithTag("Survivor");
		target = survivors[0];
		currentPathLength=0f;
		Debug.Log ("Found surivors:" + survivors.Length);
		//Debug.Break();
	}
	
	//last call
	if(survivorIndex >= survivors.Length){
		survivorIndex=0;
        
		currentPathIndex=0;
		currentPathLength=0f;
		
		Debug.Log ("Target Found");
		target.renderer.material.color=Color.yellow;
		//Debug.Break();
		return;
	}
	
	lock(this){
		seeker.StartPath(transform.position, survivors[survivorIndex].transform.position, OnPathComplete2);
	}	
}

public void OnPathComplete2(Path p){
	if(p != null)
	{
		float pathLength = getPathLength(p);	
		
		if(pathLength < currentPathLength || currentPathLength == 0f){
			Debug.Log ("Current Path Length: " + currentPathLength+"\

worse than "+ pathLength);
currentPathLength = pathLength;
target = survivors[survivorIndex];
}
}
survivorIndex++;
findTarget();
}

}
`

Thanks !

//path recompute
if(Time.time - lastAstarTime > astarInterval){
lastAstarTime = Time.time;

		seeker.StartPath (transform.position, target.transform.position, OnPathComplete);
	}

Your script is trying to find a path too often, the last one you requested was never done computing before a new one was requested. Try adding a bool to your script, so that it can only repath if the last one was done

if((Time.time - lastAstarTime > astarInterval) && mybool == true){
lastAstarTime = Time.time;

		seeker.StartPath (transform.position, target.transform.position, OnPathComplete);

mybool = false
}

and then set it to true in your OnPathComplete function

currentPathIndex = 0;
currentPath = p;
mybool = true;

Hi !
Thanks for your answer. I tried your solution, it is better but still some path get canceled somehow. I even tried mutual exclusion

`using System.Collections;
using System;
using System.Threading;
using UnityEngine;
using Pathfinding;

public class ZombieAI : MonoBehaviour {

//A*
private Seeker seeker;
CharacterController cc;
Path currentPath;

float astarInterval = 1f;
float changePathDistance = 20f;

int currentPathIndex;
float lastAstarTime;
float currentPathLength;
int survivorIndex;

public GameObject target = null;
public GameObject[] survivors;

float speed = 100f;
bool mybool = true;
bool mybool2 = true;

//initialisation
public void Start () {
	
    seeker = GetComponent<Seeker>();
    cc = GetComponent<CharacterController>();
	
}

	
//path update (target is unchanged)
public void OnPathComplete (Path p) {
	
//We got our path back
if (p.error) {
    Debug.Log(p.error);
} else {
    //Yey, now we can get a Vector3 representation of the path
    //from p.vectorPath

		currentPathIndex = 0;
		currentPath = p;
	}
}

//returns an evaluation of the length of a path, for comparison with others
public float getPathLength(Path p){
	float result = 0f;
	foreach(Vector3 i in p.vectorPath){
		result+=i.sqrMagnitude;
	}
	
	return result;
}

public void Update(){
	
	if(target != null){
		
	//path recompute
	
	lock(typeof(ZombieAI)){
	if((Time.time - lastAstarTime > astarInterval) && mybool == true){
	lastAstarTime = Time.time;
	
	seeker.StartPath (transform.position, target.transform.position, OnPathComplete);
	}
		}

	
	//movement 
	if(currentPath != null && currentPathIndex < currentPath.vectorPath.Count){
		Vector3 dir =  currentPath.vectorPath[currentPathIndex] - transform.position;
		
		if(dir.magnitude < changePathDistance && currentPathIndex < currentPath.vectorPath.Count){

			dir = transform.position - currentPath.vectorPath[++currentPathIndex];
		}
		
		cc.Move(speed * Time.deltaTime * dir.normalized);
	}
	
	//eating range
	if((transform.position - target.transform.position).magnitude < 100f)
	{
		Destroy (target);
		
	}
		
	}
	
	else{
		findTarget();
	}
	
}

public void findTarget(){
		
	//first call
	if(survivorIndex == 0){
		survivors = GameObject.FindGameObjectsWithTag("Survivor");
		target = survivors[0];
		currentPathLength=0f;
		Debug.Log ("Found surivors:" + survivors.Length);
		//Debug.Break();
	}
	
	//last call
	if(survivorIndex >= survivors.Length){
		survivorIndex=0;
        
		currentPathIndex=0;
		currentPathLength=0f;
		
		Debug.Log ("Target Found");
		target.renderer.material.color=Color.yellow;
		//Debug.Break();
		return;
	}
	
	lock(typeof(ZombieAI)){

		seeker.StartPath(transform.position, survivors[survivorIndex].transform.position, OnPathComplete2);
	}
}

public void OnPathComplete2(Path p){
	if(p != null)
	{
		float pathLength = getPathLength(p);	
		
		if(pathLength < currentPathLength || currentPathLength == 0f){
			Debug.Log ("Current Path Length: " + currentPathLength+"\

worse than "+ pathLength);
currentPathLength = pathLength;
target = survivors[survivorIndex];
}
}
survivorIndex++;

	findTarget();
}

}`

Like that it seems impossible that two paths get computed at the same time…