19 February 2016
I now know what is causing the issue with generating chunks after exiting play, but I don't have a proper fix for it. I might have a fix for the empty folders though. First, I'll explain the issue:
The problem is caused by the code I use to detect when a volume has been duplicated (ctrl/cmd+d) in the editor.
In order to do duplicate a volume properly, we need to generate a new PicaVoxel ID for the volume so that it generates its own mesh. If we don't do this, the duplicated volume will share the same mesh as the original and any edits made to one duplicate will happen on all duplicates sharing the same mesh.
The trouble is (as with all things), there is no support for detecting a duplication event in editor script. The best you can do is look at the InstanceId of the volume GameObject. For some reason, just-duplicated objects are guaranteed to have a negative InstanceId, so if that is the case then we force the mesh to be saved with a new PicaVoxel ID.
The only trouble with that is we have to check for the negative InstanceId on Awake() of a volume, so the same code gets run when exiting Play mode or when recompiling scripts, or reloading the project.
This would all be fine if Unity did not change the InstanceIds of objects every time the project is reloaded. But it appears that at some point during a project's lifecycle, Unity starts to assign negative InstanceIds to objects that have not been duplicated when the project is reloaded. I've just never been able to reproduce this problem myself, and neither has anyone else - it does not happen with blank projects.
So that's the backstory to this issue. The only way to stop the unwanted chunk regeneration altogether is to disable the duplicate check by commenting out the else block starting at line 147 of Volume.cs
I think I've found a fix for just the empty folder issue, but as I can't reproduce the overarching issue I can't test it. Hopefully someone else can:
// Change line 614 of Frame.cs (in SaveChunkMeshes()) from:
if (string.IsNullOrEmpty(ParentVolume.AssetGuid) || forceNew) ParentVolume.AssetGuid = Guid.NewGuid().ToString();
if (string.IsNullOrEmpty(ParentVolume.AssetGuid)) ParentVolume.AssetGuid = Guid.NewGuid().ToString();
Last edited 19 February 2016