Hi joel,
I’m doing dynamic meshes too and the problem is, that Meshes are not serializable, so they don’t save with the scene and don’t survive the game start in the Editor or dragging the gameObjects containing them into the project to create a prefab. This also means they don’t support any kind of Undo.
There are different ways to overcome this.
For me, the created mesh is easy to recreate - I only need to detect the following events, because they need to be handled and the System doesn’t always tell me when they happen:
1 Duplication in Hierarchy
I need to handle this, because everything that is serializable gets properly duplicated - that is: serialized and deserialized after which you have a separate copy of everything, BUT: you sharedMesh just gets referenced - so now you have something that is partly an instance, so changing parameters on any of the gameObjects, recreates the same (one and only) sharedMesh. So Depending on when you recreate your mesh, you see the following:
- Recreation on request/parameter change => both meshes change (again: because they are the same referenced sharedMesh)
- Recreation every Frame: The same mesh gets recreated twice a Frame and you only see the last one . if you deactivate the last script for tests, you see the first one while the second is deactivated.
Now I haven’t talked about mesh/sharedMesh yet, but you need to use the later, or the Editor duplicates or instances the mesh in sharedMesh and then complains about meshes being leaked.
2 GameStart
- That’s easy - this actually gets communicated with Awake() and Start(), so I can create a sharedMesh and create my dynamic Mesh.
3 Instantiating a copy from Prefab while in Editor or while the Game runs.
Same as for GameStart, I get Awake/Start
Now in your case, you said you have a voxel editor. If by this you mean that you have data structures like a 3D Array and you can completely regenerate your mesh from this(with marching cube or whatever), you basically are in the same position as me, where you don’t actually need to save the mesh, because you can recreate it anytime, but you may still want to be able to bake the Mesh, so you don’t have to do complicated calculations at runtime on mobile for example.
So that’s the way I’m goign at the moment. Recreate the mesh every time it’s not there(new, new from prefab, gamestart etc.) or the parameters changed and allow to bake it, which saves a copy of the mesh as assets, which then automatically will be linked in prefabs I create, so that when I instantiate the prefab, the mesh is already there, so my normal checks if there is a mesh work out and I don’t recreate the mesh.
Now for duplication, I need to find out if two objects point to the same sharedMesh and if so, I simply give the new object its own sharedMesh.
I also need to create a new sharedMesh if I started with a baked Mesh, but want to then dynamicly change something. I should not use the baked mesh any longer or I will change the prefab forever.
However, if your Mesh is your number one citizen that you’re editing, it gets more complicated, because then you need to have some other way of implementing Undo and Undo is needed for Tools you want to sell in the AssetStore.
The GameDraw (see AssetStore) guys implemented their own serializable copy of Mesh for this, so they don’t need to handle Undo themselves, but can let the editor do it. You basically have your own editor, so all the low-level data in your ScriptableObject doesn’t show, but write all changes to the ScriptableObjects, sso you get Undo almost for free.
Another thing I wanted to have a look into, but didn’t had time yet is AssetModificationProcessor
So… that’s pretty much my initial brain dump to this issue. I probably forgot something…
More ideas anyone?