Storing paths and light weight movement script

Hi, my A* implementation (grid graph, AIPath) is coming along nicely, but as I am planning to scale up to about 1000 AIs, I have two questions to help me go forward. In particular I plan to do the following to help performance:

  • a lot of my source and destination nodes are fixed, so I could calculate paths at the beginning of the game; is there a recommended way (or even sample code) as to how to calculate, store and retrieve paths? I’m not concerned about the memory implications of storing many paths.

  • this thread
    https://forum.arongranberg.com/t/1000-agents-and-more/8215
    mentions that “… for 1000 agents you will want to use a custom movement script or at least use the AILerp movement script (the fastest of the built-in ones). AIPath and RichAI would probably have too much overhead …”. Are any examples of such light-weight movement scripts available? I would need local avoidance to still work with such a script.

Thank you for your time.

Hi

If your destinations are fixed (and you have few of them) then you may be intersted in the FloodPath path type. See https://arongranberg.com/astar/docs/floodpath.html

This will calculate all possible paths to a given point very efficiently and then you can use the FloodPathTracer path type to calculate a path to that destination much much quicker than a normal path request.

Hi Aron,

Thank you for your quick reply. I had a look at FloodPath before, but don’t think they will quite work for my application. Is there any way to calculate and store paths for later usage given that I’m using a grid graph and AIPath? If AIPath is the problem, then I could potentially switch to AILerp.

As far as i know, the builtin pathers are re-requesting paths in certain intervals, so each returned path is likely a new one (tags etc. could have changed inbetween). But if you have fixed paths and conditions, you could use the vector list used for movement of the path to (re)store it yourself. The builtin components seem to have a method SetPath that looks useful too. Not sure how to construct valid paths though, haven’t used the system for a while. But writing your own pather shouldn’t be too hard and that way you’re free to bypass the system with precalculated stuff.

Thank you Polymo, for pointing me in the right direction. I’ll have a look at those functions and see how far I can get.

I feel like I’m halfway there, but now I’ve hit a wall. My path calculates and I have access to the individual Vector3 representation of the path, but when I try to ‘load’ the path onto a GameObject, I receive this error:

ArgumentException: You must call the SetPath method with a path that either has been completely calculated or one whose path calculation has not been started at all. It looks like the path calculation for the path you tried to use has been started, but is not yet finished.

This is my code:

var path = ABPath.Construct(playerObject.transform.position, targetObject.transform.position, OnPathComplete);
AstarPath.StartPath(path);

...


void OnPathComplete(Pathfinding.Path path) {

    Debug.Log(path.error);

    GameObject pathFinder = new GameObject();
    var seeker = pathFinder.AddComponent<Seeker>();
    var modifier = pathFinder.AddComponent<RaycastModifier>();
    modifier.useGraphRaycasting = true;
    modifier.useRaycasting = false;
    seeker.PostProcess(path);

    foreach(var x in path.vectorPath) {
    	Debug.Log(x.ToString());
    }

    GameObject player2 = GameObject.CreatePrimitive(PrimitiveType.Cube);
    var pfAIPath = player2.AddComponent<Pathfinding.AIPath>();      
    pfAIPath.SetPath(path);
}

The first Debug.Log prints “false” and the foreach loop prints all the right vectors. I’m surprised it would call the OnPathComplete method and then complain about the path not being complete.

Hi

Ah, that particular bug was fixed in 4.3.15 (in the beta)

4.3.15 (2020-03-11)
-Fixed ai.SetPath did not accept paths if you called it from the OnPathComplete callback for the path.

In the non-beta version everything you do will work, but you’ll have to call SetPath after OnPathComplete has finished I’m afraid, otherwise it will complain.

You can find the beta here if you are interested: https://www.arongranberg.com/astar/download

I do still think that the FloodPath is the right way to go for you. Calculating a FloodPathTracer path is extremely fast (only a hashmap access for each node in the path) so you do not worry about that part being slow. It also allows for the agents to go off-track and find their way back much more easily.

Ok, that would explain it. I just followed the installation procedure for the beta and everything worked ok, but after installation I get the following errors:

Screenshot at 2020-07-04 22:42:38

The reason why I thought the FloodPath isn’t working in my particular case is that I’m working on an online multiplayer game. I would like to pre-calculate all paths on the server and send them to clients as sections of the game’s map become available during game play.

Hmmm, alright.
You may be interested in the ABPath.FakePath method in that case
See https://arongranberg.com/astar/docs/abpath.html#FakePath

It looks like your computer needs some additional library or something to run burst properly. I’m not sure how to solve that issue specifically, but you might find info in the Unity docs.

Alternatively you can work around the issue (in the non-beta) using the FakePath method. Just do something like this:

ai.SetPath(ABPath.FakePath(path.vectorPath, path.path));

Also something which might be useful for you to know is that the AIPath movement script does not require the nodes array in the path to be filled. So you can just do

ai.SetPath(ABPath.FakePath(path.vectorPath));

This might be useful for you if you are going to send paths over the internet.

I played around with the beta version for a while, but it turns out I would need to update my Linux version (I’m not keen on doing that) to make it work. However, the FakePath method is exactly what I was looking for, thank you so much for pointing me in that direction! Being able to use it with just the vectorPath is the icing on the cake, it saves me from serializing objects to send them over the internet. Wonderful!

One last question if I may: will I need a graph on the clients’ side? Or does the AIPath script simply follow the path that I’m providing it with? In other words, is the graph only used for calculating the path or also for moving of the AI and for local avoidance?

The AIPath script only uses the vector path. Unless if you use the ‘constrain to graph’ option in which case it requires a graph to be present.

The local avoidance doesn’t need access to a graph either.

Fantastic, this is better than I hoped for!