Here is the project in question. There are a bunch of scripts, but the one we’re concerned with is “GenerateMap.cs”, it’s in the Assets/Scripts folder.
This project loads unmodified Quake 1 maps, and recreates them in Unity, just like it says on the tin. Parsing the maps themselves into C# objects is very fast. Even massive (by Quake 1 standards) maps are fully parsed into ready to use C# objects in less than a second. The issue is when it’s time to make GameObjects for them.
Currently I’m making every surface in the map (called faces in .bsp lingo) into its own GameObject. On small deathmatch maps this results in about 3k objects, startup time of around a second, and 100fps. Great. On the massive maps, I end up with 32k GameObjects. It takes around 20 seconds to start, though performance isn’t too bad once it’s loaded, considering.
I’m not so concerned about the performance once the game is running, as I can implement the “vis” data from the .bsp and turn off the renderer on gameobjects that aren’t visible, but how can I speed up the generation of the GameObjects? Or is there a better way?
Each object has the following:
- A mesh filter and renderer
- A mesh collider
- A texture that is generated at runtime from the .bsp itself
In case you can’t be bothered to look at the code, the basic process I’m using is this. Foreach face, create a gameobject, calculate the verts and tris for the mesh, calculate the uvs for the mesh, add components I need, add the verts, tris, and uvs to the mesh, recalculate normals, mark the object as static, done and onto the next face.
It’s very simple, but with so many objects, it’s slow to start up on the big maps. I don’t have Unity Pro, so I can’t use the profiler. Is there a valgrind/cachegrind type inspection I can perform somehow? Anyone have any tips on how I can speed this process up?