Using RelocateNodes with a navmesh graph

I’m putting together a project not too different from the other streaming worlds discussed on the forums, except I am using NavMeshes instead of grid graphs.

To do this, I’m trying to create a new NavMeshGraph by using DeserializeGraphsAdditive, and then shifting the added graph to the new location using RelocateNodes (I also set the graph’s offset to the new position). But nothing seems to happen unless I also call Scan() on the new graph. This looks like because the originalVertices isn’t serialized with the graph, so RelocateNodes() just returns doing nothing. Should it serialize the originalVertices or just form a delta transform (new * old.inverse) to shift the vertices? (I did the latter and this fixed RelocateNodes doing nothing, so I don’t need to scan anymore)

Also I think there is a bug in RelocateNodes: as it goes and updates all the node positions and link costs, it looks like a mix of old and new positions are used when calculating the costs (since it updates a node’s position, then loops over connections which potentially point to nodes that have not yet updated their positions). Should it be broken into two loops?

After doing all this and getting multiple graphs loaded, moved and connected by adding new UserConnections, pathfinding seems broken when pathing to the newly added graph. I can send a screenshot to illustrate, but basically when trying to path to a location on the new graph, a path looping around the old graph is generated.

Any suggestions? Is it possible to load serialized graphs dynamically without needing to Scan or perform heavy fixups that would cause hitching in the game?

Oh, I just found that if I disable the funnel modifier, the paths seem to work. So somehow the funnel modifier is destroying the path whenever it is on the new graph.

Ah figured it out – it’s not really related to the funnel modifier, it’s just because the funnel modifier uses the graph index from the nodes.

When deserializing graphs using DeserializeGraphsAdditive, the node indices point to the graph index when they were serialized. This is wrong… I added some code to reset them to the new graph index, and all seems to work.

Are there any other known limitations when using DeserializeGraphsAdditive?

You seem to have found a lot of bugs there. Thanks for reporting them and also that you took the time to figure out exactly what went wrong. I have added the above to my todo list.

The only limitation I think would be the graph indices being messed up as you discovered. I cannot think of any other limits. But I have to say that I do not test that function frequently, so it might have more bugs which I or you have not found yet.

Thanks Aron. I’ll update if I find anything else.

Fwiw, this is the new method I added to shift navmesh nodes. It only translates, but is a lot faster since it avoids all the vector3->int3->vector3 conversions, and skips updating costs for connections within the graph (since we know they don’t change under a translation).

`
public void TranslateNodes(Int3 delta) {
if (vertices == null || vertices.Length == 0) {
return;
}

for (int i=0;i<vertices.Length;i++) {
	vertices[i] += delta;
}

int index = AstarPath.active.astarData.GetGraphIndex(this);

for (int i=0;i<nodes.Length;i++) {
	MeshNode node = (MeshNode)nodes[i];
	node.position += delta;
			
	// The only reason it is safe to update the node positions and connections in
	// the same loop is because we only update costs for connections off-grid.
	// Since we'd just translated, all on-graph connection costs don't change and
	// we don't update them.
	if (node.connections != null) {
		for (int q=0;q<node.connections.Length;q++) {
			Node connection = node.connections[q];
			if (connection.graphIndex != index) {
				node.connectionCosts[q] = (node.position-connection.position).costMagnitude;
			}
		}
	}
}

}
`

quick update for anyone who finds this thread: beware using RelocateNodes or similar if you have the pro package. you need to add code to move the BBTree as well, or pathfinding goes totally haywire.