I am currently designing a maze game in unity and have some enemy AI which chases players around the maze. If the player gets to a certain tile on the maze it'll generate a new maze with slightly larger dimensions.
I've been using the unity AI NavMeshSurface class to achieve this and calling surface.BuildNavMesh()
to generate the nav mesh once the level has been generated.
The current level's maze game object(s) get destroyed each time the level is regenerated:
public void GenerateNewMaze(int rows, int columns) { mazeData = dataGenerator.FromDimensions(rows, columns); DisplayMaze(); surface.BuildNavMesh(); } public void DisposeOldMaze() { GameObject[] mazeObjects = GameObject.FindGameObjectsWithTag("Generated"); foreach (GameObject mazeObject in mazeObjects) { Destroy(mazeObject); } }
The first time I run this it works perfectly:
However from the second onwards I start getting some strange gaps:
I thought maybe the surface somehow still had the old data after doing some googling and I tried a couple of solutions such as surface.RemoveData()
and NavMesh.RemoveAllNavMeshData()
before building the navmesh again but I seem to get the exact same results.
Currently I can only think to create a new NavMeshSurface per maze generation but that seems overkill and unnecessary.
The tutorial I followed to do this was: https://www.youtube.com/watch?v=FkLJ45Pt-mY
Turned out to be something strange I'd done. For those interested, it was my misunderstanding that calling Destroy on my maze objects is not finished until the frame has ended. So the NavMesh was generating for both the new and the old maze
Therefore I needed to dispose of the current maze objects in the current frame and update the NavMesh in the following. I did this with the following code by calling FlagLevelForProgression
instead of GenerateNewMaze
:
public void FlagLevelForProgression()
{
mazeConstructor.DisposeOldMaze();
// Load any stuff we need to...
canProgressToNextLevel = true;
}
void FixedUpdate()
{
if(canProgressToNextLevel)
{
GenerateNewMaze();
canProgressToNextLevel = false;
}
}