A* Pathfinding Project

Best way to manually compare and choose between multiple paths


#1

I have an array of possible destinations, and I’d like to be able create paths to each one, and then compare them to determine which one to follow. Most of the time, I would be specifically looking for the shortest path (in which case MultiTargetPath would work best) but I may want to evaluate them on different metrics or even do something like pick randomly from the 3 shortest paths in order to add a level of unpredictability to the AI.

I started by loosely following the code found here, and at first glance, it seems like it should work perfectly, but I’m having some trouble fully implementing it. Namely, after I have a path object that I’ve determined is the one I want, how do I make the seeker follow it? I think a lot of my confusion is due to the bulk of tutorials focusing on using the seeker class for path finding where as this example uses ABPath and AstarPath, and I’m just not sure what the consequences and differences are of using those instead of Seeker.

Would really appreciate any help!


#2

Hi

If you are using one of the built in movement scripts (e.g. AIPath) then you can use the SetPath method.
Something like this:

var bestPath = calculate the best path in whatever way you with
// You may want to call seeker.PostProcess(path) on the paths if you are using any modifiers
seeker.PostProcess(bestPath);
// All built-in movement scripts implement the IAstarAI interface
IAstarAI ai = GetComponent<IAstarAI>();
// Disable the AI's internal path recalculation code. Otherwise it may replace your path very quickly.
ai.canSearch = false;
// Make the AI follow the path
ai.SetPath(bestPath);

The Seeker class is intended to search one path at a time. However in this case you will want to use the AstarPath class directly as then you can search multiple paths simultaneously.


#3

Thanks for the reply!

So far, I’ve been using my own movement scripts. In that case, would I simply apply the post processing with the seeker, and then use the vectorPath to apply movement however I wanted?

This is what I currently have (shortestPath being the choosen path with postProcessing applied). I also just use the x, z components of the vector 3 to check the distance to the next waypoint as I couldn’t figure out how to get the navmesh to accurate match the height (y) of my terrain)

float distanceToWaypoint;
                    distanceToWaypoint = Vector2.Distance(new Vector2(enemyTransform.position.x, enemyTransform.position.z), new Vector2(shortestPath.vectorPath[currentWaypoint].x, shortestPath.vectorPath[currentWaypoint].z));
                    if (distanceToWaypoint < nextWaypointDistance)
                    {
                        if (currentWaypoint + 1 < shortestPath.vectorPath.Count)
                        {
                            currentWaypoint++;
                        }
                        else
                        {
                            Debug.Log("End of Path");
                        }
                    }
                    inputs = new AICharacterInputs();
                    inputs.MoveVector = (shortestPath.vectorPath[currentWaypoint] - enemyTransform.position).normalized * 0.2f;
                    inputs.LookVector = shortestPath.vectorPath[currentWaypoint] - enemyTransform.position;

#4

Yes, that should work.

distanceToWaypoint = Vector2.Distance(new Vector2(enemyTransform.position.x, enemyTransform.position.z), new Vector2(shortestPath.vectorPath[currentWaypoint].x, shortestPath.vectorPath[currentWaypoint].z));

You could also use

distanceToWaypoint = VectorMath.MagnitudeXZ(enemyTransform.position - shortestPath.vectorPath[currentWaypoint]);

You could also experiment with the PathInterpolator class which the AIPath script uses internally. It’s not that well documented at the moment though.