I have 3 graphs for my project. 1 navmesh graph for enemies that can walk on walls and ceilings, 1 point graph for flying enemies, and another navmesh graph for NPCs and other objects that walk on the ground. I have all 3 of these graphs working flawlessly.
The trouble that I’m running into is that I need to update the tags of nodes on a regular basis. I tried using UpdateGraphs(bounds)
for the nodes that I want to update, but updating the tags for all 3 graphs comes at a pretty huge performance hit. Looking at several other threads such as:
It appears that I am definitely not the only one that faces performance challenges with UpdateGraphs()
. My specific issue is exacerbated because I need to apply the updates to three graphs, thus tripling the performance impact. This leads to frame freezes of over a second, which is not at all ideal in a game.
With these issues with UpdateGraphs()
, along with several other use cases specific to my game, the optimal way to proceed is going to be using work items to update the graph at runtime. I’m okay with a second or two delay in getting tags updated, as my tag logic requires multiple CheckSphere
and Raycast
calls. This amounted to the following code:
IEnumerator PathingTagsLogic()
{
// Iterate through all of the graphs (in my case 3)
for (int i = 0; i < AstarPath.active.data.graphs.Length; i++)
{
// Create a work item for a graph
AstarPath.active.data.graphs[i].GetNodes(node =>
{
// Check if a node overlaps with an object on a specific layer, and apply a tag if it does
if (Physics.CheckSphere((Vector3)node.position, AstarPath.active.data.navmesh.scale * 0.71f, 1 << 14, QueryTriggerInteraction.Collide))
{
node.Tag = 2;
}
if (Physics.CheckSphere((Vector3)node.position, AstarPath.active.data.navmesh.scale * 0.71f, 1 << 12, QueryTriggerInteraction.Collide))
{
node.Tag = 1;
}
yield return null;
});
}
}
The above coroutine, when called, should iterate through all of my graphs, check for nearby collisions near nodes, and update them accordingly. However when I try to run this, it says error CS1621: The yield statement cannot be used inside an anonymous method or lambda expression
.
Is there a way that I can call GetNodes without using a lambda expression so I can run it inside a coroutine?