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