Support Forum

Problem with replacing tiles and Navmeshcut/add

I have a problem with recast graph tiles affected by Navmeshcut/Add reverting to a previous state after being replaced.

In this image, you can see two tiles that are positioned below the others. These tiles are in the location where previously the navmesh cuts/adds were applied to the recast graph. They are the original tiles that have somehow been restored.

This happens when the cut/add components are disabled, the original state of the tiles is restored, despite them having been replaced since the cut was made.

PS: Apologies for spamming forum recently. I do try very hard to find the answers first and it is only after a couple of days debugging before I post, after I think I have run out of options.

I solved the above problem, but I now have a new problem.

The above issue is solved by calling the following method after the NavmeshCut/NavmeshAdd is disabled. this will stop the system restoring the original tiles:
AstarPath.active.navmeshUpdates.DiscardPending();

The new problem is that after shifting the world origin, I replace all the recast tiles in their new position eg: origin shifts 2 tiles north, all tiles are shifted in the recast graph accordingly using graph.ReplaceTile. I then use navmeshcut/add, to make changes to the recast tiles. However the cuts/add are not applied to the newly loaded mesh, these tiles are swapped for the tiles that were originally located in this space before the origin shift, with the cuts/adds applied.

It seems that graph.ReplaceTile, does not reset the unchanged state for the tile. Is there a way to force the replaceTile mesh to be the new unchanged state for that tile?

To demonstrate here is a quick video. I have disable the terrain to make it easier to see what is going on. After the origin shift, the recast graph is correct, but once the navmeshcut/add is applied, the affected tiles are updated using the tiles that were located in that position from before the origin shift.

I have a hack solution that seems to work. This changes the core code, which I prefer not to do.

I think the problem is that activeTileTypes in TileHandler, needs to be recreated after a tile is replaced. To achieve this I added the below code to the bottom of NavmeshBase.ReplaceTile. I also had to expose the method TileHandler.UpdateTileType, by making it public

This will recreate the TileType for the tile after it is replaced.

I feel like a monkey pressing keys on a typewriter trying to work this out, because there are a lot of moving pieces and I don’t fully understand the inner workings of A* Pathfinding Project.

Is this hack solution headed in the right direction? Or is there a “proper” way to do this using existing methods?

// Added to bottom of method NavmeshBase.ReplaceTile

			if (navmeshUpdateData != null && navmeshUpdateData.handler != null)
				navmeshUpdateData.handler.UpdateTileType(tile);

Hi

Hmm, there’s no proper method right now. What would be required is to call

navmeshUpdateData.OnRecalculatedTiles(new NavmeshTile[1] { tile });

But it cannot be done in ReplaceTile, because the tile handler calls that itself when it replaces tiles after navmesh cutting.

Thanks that helps me understand a bit better how your code manages things. My hack solution is working for my situation, and so I will stick with it. I understand how it might break some features, but as I am not using them, it should be ok.