Support Forum

GetNodesInRegion and GetBounds high cost

Hi Aron, I’m noticing that the GetNodesInRegion and GetBounds procedures have a very high cost.
Here is a picture of the costs:

Should I use another method to get the cells for an agent?

Hi

Is it possible for you to use the GetNodesInRegion(IntRect, GridNodeBase[]) overload? It is significantly faster.
See also Documentation

thanks for the info, i’m trying to do it this way but it doesn’t get the nodes, could you give me an example?
Currently I am trying to do it on an agent in the following way:

float vRadius = this.Collider.radius;
int vXMin = Mathf.RoundToInt (transform.position.x - vRadius);
int vYMin = Mathf.RoundToInt (transform.position.y - vRadius);
int vXMax = Mathf.RoundToInt (transform.position.x + vRadius);
int vYMax = Mathf.RoundToInt (transform.position.y + vRadius);
ListvNodesAgent = gg.GetNodesInRegion(new IntRect(vXMin, vYMin, vXMax, vYMax));

You can use gg.GetRectFromBounds to get an IntRect from a bounding box.

Note that the GetNodesInRegion overload which takes a buffer array as the second argument is the one I meant (see link in previous message). The ones which return a list are slower.

1 Like

Could you get or create the rect in some other way to make it more efficient? I see that GetRectFromBounds also has a significant cost, here is the cost image:

Hi

Are you sure the JIT is warmed up at that point (i.e. did you call the method multiple times)? I find it really unlikely that it would take that long.

I call it every time an agent parks or starts walking, the image reflects 1 call of this function, this is what I do in the script:
var gg = AstarPath.active.data.gridGraph;
IntRect vRect2 = gg.GetRectFromBounds(this.collider.bounds);
GridNodeBase[] vGridNodeBase = new GridNodeBase[MaxNodesInRegion]; → (MaxNodesInRegion assigned in awake)
int vTotalNodes = gg.GetNodesInRegion(vRect2, vGridNodeBase);

I’d recomment profling GetRectFromBounds using custom Profiler.BeginSample/EndSample blocks instead of using deep profiling. Deep profiling has a tendency to skew profling results, especially cheap functions that call many other functions.

For better performance you could also cache the vGridNodeBase array to avoid allocating a new one every time.

I’ll try to check it with the custom profiler to see how it works.
I always cache vGridNodeBase for when I start walking to read this cache, but when I park I always need to re-calculate it since this agent will be in another new position.

THX :slight_smile:

How can I know the size of the GridNodeBase for each collider?
I currently calculate it like this:
float vRatio = MyBoxCollider.size.x;
MaxNodesInRegion = Mathf.CeilToInt (vRatio / AstarPath.active.data.gridGraph.nodeSize) * 2;
MaxNodesInRegion = MaxNodesInRegion * MaxNodesInRegion;
but this sometimes stays small

You can use

IntRect vRect2 = gg.GetRectFromBounds(this.collider.bounds);
int MaxNodesInRegion = vRect2.Area;
1 Like