Hello!
I have worked with the MultiTargetFree example. Basically what it does now is that it calculates the paths,and the shortest is set “SetPath(bestPath);”
Now the problem is that the ABPath calculation doesn’t seem to take GraphUpdateScene into account. I tested this by changing the MultiTargetFree to the AIDestinationSetter.
The best thing that I would like, is that the destination of bestPath will be used as a target like in AIDestinationSetter rather than SetPath. And then in Update write it like AIDestinationSetter (if (target != null && ai != null) ai.destination = target.position;)
That means that target = endofpath or that the return of the script is the object with the closest path instead of the actual path
A second solution I can think of, if is there is some way to use GraphUpdateScene into ABPath.
The code:
public List<Transform> targets;
private Path[] lastPaths;
private int numCompleted = 0;
private Path bestPath = null;
int walking = 0;
IAstarAI ai;
int index;
private float length;
int pathspecific = 0;
void Start()
{
targets = new List<Transform>();
GameObject[] farm = GameObject.FindGameObjectsWithTag("farm");
foreach (GameObject test in farm)
{
targets.Add(test.transform);
}
StartCoroutine(waitForScan());
}
IEnumerator waitForScan()
{
yield return new WaitForSeconds(1);
SearchClosest();
}
protected override void Awake()
{
base.Awake();
ai = GetComponent<IAstarAI>();
}
public void SearchClosest()
{
targets = new List<Transform>();
GameObject[] farm = GameObject.FindGameObjectsWithTag("farm");
foreach (GameObject test in farm)
{
targets.Add(test.transform);
}
//If any paths are currently being calculated, cancel them to avoid wasting processing power
if (lastPaths != null)
for (int i = 0; i < lastPaths.Length; i++)
lastPaths[i].Error();
//Create a new lastPaths array if necessary (can reuse the old one?)
if (lastPaths == null || lastPaths.Length != targets.Count) lastPaths = new Path[targets.Count];
//Reset variables
bestPath = null;
numCompleted = 0;
//Loop through the targets
for (int i = 0; i < targets.Count; i++)
{
ABPath p = ABPath.Construct(transform.position, targets[i].transform.position, OnTestPathComplete);
lastPaths[i] = p;
AstarPath.StartPath(p);
}
}
public void OnTestPathComplete(Path p)
{
if (p.error)
{
Debug.LogWarning("One target could not be reached!\n" + p.errorLog);
}
//Make sure this path is not an old one
for (int i = 0; i < lastPaths.Length; i++)
{
if (lastPaths[i] == p)
{
numCompleted++;
if (numCompleted >= lastPaths.Length)
{
CompleteSearchClosest();
}
return;
}
}
}
public void CompleteSearchClosest()
{
//Find the shortest path
Path shortest = null;
float shortestLength = float.PositiveInfinity;
//Loop through the paths
for (int i = 0; i < lastPaths.Length; i++)
{
//Get the total length of the path, will return infinity if the path had an error
float length = lastPaths[i].GetTotalLength();
if (shortest == null && length > 0.1 && length < 10 || length < shortestLength && length > 0.1 && length < 10)
{
shortest = lastPaths[i];
shortestLength = length;
}
}
//Debug.Log("Found a path which was " + shortestLength + " long");
bestPath = shortest;
}
public void Update()
{
if (bestPath != null && bestPath.vectorPath != null && walking == 0)
{
ai.SetPath(bestPath);
walking = 1;
}
//Highlight the best path in the editor when it is found
if (bestPath != null && bestPath.vectorPath != null)
{
for (int i = 0; i < bestPath.vectorPath.Count - 1; i++)
{
Debug.DrawLine(bestPath.vectorPath[i], bestPath.vectorPath[i + 1], Color.green);
}
}