World Editing and Persistence

World editing and persistence is something that has been avoided so far due to the complexity, but it has finally been tackled.

Editing the world outside of play mode is something that I really wanted to do. I really want to do scenes/worlds that are setup specifically as test cases. Editing the world in play mode to create cases, like the unit not having a path to the player due to holes in the terrain, was not time effective.

I was not really looking to tackle persistence yet, but there were a number of gotchas with editing the world via the scene view in the Unity Editor. Everything was great if I generated the world data fresh, but any action like saving a script or entering play mode would cause the World class data to reset. So persistence it is!

I ended up going with a Scriptable Object to save the world data for now. I am not super familiar with Scriptable Objects and quickly learned that not all objects would persist. Specifically my multi-dimensional arrays that I was using the represent my world.

In the end I am very happy with the system, even though it took a lot longer than I figured it would. Now I can Generate/Save/Load world data and edit in in Edit Mode through the Scene View.

One thing of importance during all this, I updating the NavMeshSurface dynamically… the bounds you are updating needs to be larger than a NavMeshSurface tile size. This was something that I discovered a while back, but forgot.

To ensure this isn’t an issue in the future I wrote code to ensure it always larger.

float halfTileSize = (navMeshBuildSettings.tileSize * 
      navMeshBuildSettings.voxelSize * 0.5f) + 1f;
Vector3 extends = bounds.extents;
extends.x = extends.x < halfTileSize ? halfTileSize : extends.x;
extends.y = extends.y < halfTileSize ? halfTileSize : extends.y;
extends.z = extends.z < halfTileSize ? halfTileSize : extends.z;
bounds.extents = extends;