AI of different size in Recast Graph


#1

Someone know how to do that?

Let’s say I have basic enemies with a 0.5m radius. Then bigger enemies of a 1m radius. And even bigger at 1.5m, etc.
They all can walk in the same areas, but obviously the bigger one should stay further away from walls.

How am I supposed to do that? Two different navmesh on top of each other, with different radius? If so, how to assign a seeker to a specific navmesh?

I know about “graphMask”, but there is no way to flag a specific graph as having such mask. Looks like it’s just “The first graph is the first bit, the second is the second bit, etc”. Which means I should always had all the graph possible, even if some specific enemies doesn’t exist in an area?


Some clarification with multiple graphs
Questions about graph creation
#2

Hi

Sorry for the late answer.
For this you would need, as you say, multiple recast graphs.
Since this is a relatively rare thing to need, this functionality is not exposed in the inspector. However in the movement script when it calls seeker.StartPath an additional argument can be added which indicates which graph to search on. Like this

 // This is the index of the graph that you want to search on
 // The first graph in the graphs list will be at index 0, the second one at index 1 and so forth.
int graphNumber = 2;
int graphMask = 1 << graphNumber;
seeker.StartPath(startPoint, endPoint, null, graphMask);

#3

Please, re-read the last part of my first post. I’m aware of graphMask, but I cannot guaranty that every scene will have all the enemy types. Which mean, it would be wasteful to have navmesh that are never used. For example, boss fight may use only a single navmesh with very large character radius.

Example of the navmeshes in different scenes:
Scene 1: Tiny, Small and Huge size
Scene 2: Tiny and Normal size
Scene 3: Huge size
Scene 4: Tiny, Small, Normal and Huge size

“graphMask” assume the number of navmesh is fixed, and also that their “order” is also constant.

We were hoping for a way to “flag” or “tag” a specific navmesh and have the Seeker only use the navmesh that have the proper flags. Or even that a Seeker could have a radius, and it would use the navmesh built with the nearest radius.


#4

Hi

Ok. Currently there is no built in function that does that, but you can easily make your own function which looks up the index based on some value or the name of the graph (you can rename the graphs in the inspector):

public int graphMaskForGraphName(String name) {
     var graphs = AstarPath.graphs;
     for (int i = 0; i < graphs.Count; i++) {
          if (graphs[i].name == name) {
               return 1 << i;
          }
     }
     Debug.LogError("Could not find a graph with the name '" + name +"'");
     return 0;
}

public int graphMaskForRadius(float radius) {
     var graphs = AstarPath.graphs;
     RecastGraph bestGraph = null;
     int bestMask = 0;
     for (int i = 0; i < graphs.Count; i++) {
          var rg = graphs[i] as RecastGraph;
          if (rg != null && (bestGraph == null || Mathf.Abs(rg.characterRadius - radius) < Mathf.Abs(bestGraph.characterRadius - radius))) {
              bestMask = 1 << i;
              bestGraph = rg;
          }
     }

     return bestMask;
}

Note: I typed this directly in the forum, so there may be some minor compiler errors.


#5

There are many scales of enemies in my game. Could it be done by having each node know the maximum radius an agent can be to use the node? It would probably use Physics.CheckSphere, then can I feasibly implement this feature because it would be too much to do it for each node, but rather nodes should interpolate the max radius between the nearby sphere checks?


#6

@PrecisionCats

Yes, that could be done too (assuming a grid graph). This is somewhat possible out of the box by using the ‘erosion uses tags’ checkbox for grid graphs. See https://arongranberg.com/astar/docs/gridgraph.html#erosionUseTags

For other users seeing this thread, this documentation page is related: https://arongranberg.com/astar/docs/multipleagenttypes.html