- Home /
Combining Meshes at Runtime for NavMesh Generation
Hey all, For the current project I'm working on, I need to generate a navmesh for navigation of a city landscape. I've got the navmesh set up to generate at runtime but I'm having an issue due to one of my outside libraries. I'm using Mapbox to generate meshes and it creates two meshes, one for the buildings and one for the underlying map, like this: The underlying map The buildings layered on top The objects are structured so that there's a parent gameobject with one child, the map, and the map has one child, the buildings.
The main issue I'm trying to solve is that when I generate the navmesh, it runs under the buildings and my navmesh agents can't route around them.
Things I've tried:
Marking the buildings as Navmesh obstacles. The obstacle bounding boxes were too large and so navigating through alleys was impossible
Apply Navmesh Modifier Volume to the buildings
Combining the meshes
When I try to combine the meshes, I get some very strange behavior where only the rooftops are visible, like this:
I'm not too worried about the material but I am confused as to why my buildings are missing walls.
The meshes are combined with a couple of code snippets, the first is a script that gets attached to the buildings when they are generated by mapbox. All it does is call a meshcombiner object on the building's parent(The map tile):
MeshCombiner mc = GameObject.FindGameObjectWithTag( "MeshCombiner" ).GetComponent<MeshCombiner>();
mc.ApplyToMapTile( gameObject.transform.parent.gameObject );
And the ApplyToMapTile function looks like this:
public void ApplyToMapTile( GameObject tile ){
CombineInstance[] meshes = new CombineInstance[3];
// grab tile mesh
MeshFilter tmf = tile.GetComponent<MeshFilter>();
meshes[0].mesh = tmf.mesh;
meshes[0].transform = tmf.transform.localToWorldMatrix;
// grab building mesh
MeshFilter[] bmf = tile.GetComponentsInChildren<MeshFilter>( true );
meshes[1].mesh = bmf[0].mesh;
meshes[1].transform = bmf[0].transform.localToWorldMatrix;
meshes[2].mesh = bmf[1].mesh;
meshes[2].transform = bmf[1].transform.localToWorldMatrix;
// Then deactive the building
foreach( Transform child in tile.transform ){
if( child.gameObject.name == "building" ){
child.gameObject.SetActive( false );
}
}
meshHolder = new Mesh();
meshHolder.CombineMeshes( meshes, true );
tile.GetComponent<MeshFilter>().mesh = meshHolder;
Where meshHolder is just some storage in the class.
All of the code is available in the Github repo
So, I have two main questions
Is combining the meshes before generating the navmesh a reasonable solution to original navmesh problem ( The navmesh going under buildings and making it unusable ) ? Is there a better solution?
What am I doing wrong combining the meshes to end up with just the rooftops?
Thanks all
Answer by Akathon · Jun 22, 2018 at 09:27 PM
I've got two ideas that might be easier than what you are doing:
Generate the map mesh with holes where the buildings are located.
Add a flat plane to the bottom of the building mesh
Your answer
Follow this Question
Related Questions
How to create a spherical navigation? 1 Answer
NavMesh with geometry mesh generated at runtime 1 Answer
How can you access the Navigation Mesh Data ? 2 Answers
Multiple Navmesh Bakes 2 Answers