In my project, there are large numbers (think 4-digit numbers) of 3D meshes that are created or modified one by one, or in groups, at runtime (based upon user interaction). These meshes have the following properties:
- They are rather "simple" (usually comprising less than 20, or even 10, triangles).
- Barely any two meshes will be exactly the same, as their geometry (e.g. location and number of vertices) varies based upon their environment/the location of other meshes in ways that cannot be described as a general geometric transformation (such as scaling).
- The concrete shape of the meshes adheres to a general "pattern" (for instance, all meshes range from a "start point" at (0, 0, 0) to an end point at (0, 0, length)), although the concrete shape will be determined per mesh (based upon an external configuration, or supplied by plugin code, etc.).
- The meshes will be oriented in different ways in the scene. The code that generates the meshes does not need to know about this, though.
All of these are no problems as such. The straightforward way I had thought of was to create a GameObject
for each mesh, with a MonoBehaviour
subclass attached that generates vertices, normals, and so on for the Mesh
object of a MeshFilter
component.
The Transform
of each GameObject
can then conveniently be set according to the desired orientation of the mesh.
However, I have read various worrying reports that Unity does not cope well with large numbers of GameObject
instances in the scene. For instance:
- "To put this in perspective, I was seeing crashes when creating 16,384 game objects (128 x 128), but I didn't see the same crashes until attempting to create 2,359,296 Scriptable Objects (1536x1536)." (Unity Answers: Why would you use a scriptable object versus an empty gameobject?)
- "In Unity, I can only manage ~25,000 bullets at 60 FPS, and they're just sitting there, not being processed. ~25,000 GameObjects with only a transform component and a sprite renderer component, no physics, doing nothing but being drawn every frame." (Unity Answers: How to improve performance with 10,000s of GameObjects?)
- "my script works perfecly fine when I'm using small map ( under 1000 game object), but when I try to load huge map, for exemple 200 tile x 200 tile map, it means 40 000 game object, it takes a lot of time to start the game and it is very very laggy." (Unity Answers: how to have a scene with millions of gameObject ?)
- "Making every block a separate GameObject is extremely inefficient; the standard way is to create mesh chunks that each contain many blocks." (Unity Answers: Max number of Gameobjects (5000?))
Based upon these resources, I figure I have various ways to proceed (that are not mutually exclusive):
- I continue as described above, but do not activate all the
GameObject
instances with my meshes, so they only serve as mesh geometry containers that a transformation can be applied to. This sounds actually exactly like what I want (my objects do not need any self-controlled behavior), but a brief test indicates disabling actually shuts down drawing of the object, as well. As my players might zoom out far enough to see all objects at a time, this does not really solve my issue. - I do not store my meshes as individual
GameObject
instances with meshes, but I combine several of them into one large mesh. I think it's well feasible to group a few hundred meshes and combine their geometry into a singleMesh
object. I'd lose the individualGameObject
Transform
features, but I could of course apply the appropriate transformation on all the vectors returned for any given object myself. The possible issue I'm seeing here is that if one of my objects changes, I may have to recreate all the vertex, normal, color, etc. arrays for the entire chunk of hundreds of objects. - I figure out which meshes are actually visible at any given time, and only generate
GameObject
instances for these meshes. Well, my objects are going to be spread across a map, and one will be able to see at least a very simple (outline) version of each of them when zooming all the way out. I might then create a combined low-res version of those objects that are farther away, but ultimately, this leaves me with the same issues as above, with the combined mesh.
Thus, my question is: Is using chunks of combined meshes (as one actual Mesh
object per chunk, possibly split into several sub-meshes to support different textures) a viable way to go in my situation, despite the outlined issues with updating individual "inner" meshes?