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+"\
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