Is Instantiating bullets/many objects always bad for performance?

I’m trying to understand exactly what it is about Instantiating many objects that gives the performance hit that is often mentioned here. Is it increased drawcalls, the loading/creation of each new object instance, or a performance limitation of the function itself, what exactly? I can’t find detailed information about this and I would like to understand at least some of the key circumstances when to avoid Instantiation? I’ve only found two optimization videos from Unite which discuss Instantiation, but they don’t actually explain why it can be bad for performance only that it is.

In my specific case I am firing projectiles from a weapon. The fire rate is quite fast (up to 1200 rounds per minute) with each round/bullet getting destroyed either upon impact or after a certain time, if it hasn’t hit anything. I’ve tested the weapons in my scene firing at and above the maximum rate and with as many as 100 rounds at a time, but I haven’t noticed a drop in performance at all. The frame rate is quite stable; and since my bullets are only empty gameobjects with a simple trail, most of them get batched giving no significant draw call increase either. So I’m confused as to whether in my case I should still try to avoid using Instantiation and attempt the less straight forward pooling solution?

1 Answer

1

Yes, it is always bad for performance and should be avoided in all but exceptional circumstances. The actual process of instantiation in Unity is slow due the allocation and construction of the game object and components and all of the .NET reflection happening with the serialization of attached components to get their settings copied. I’m guessing a bullet doesn’t have many scripts and hence deals with it better than an enemy would in your case. In any circumstance there is likely to be a Garbage Collection after instantiation etc etc Avoiding instantiation has nothing to do with the number of draw calls.

You should have those bullets instantiated and invisible (actually I’m kinda surprised you actually model the projectiles anyway with such a rapid firing weapon), then activate them when you need them, because even if it is fast enough on your test rig it might not be on someone else’s computer, it would be a dog on a phone. Really you are also wasting ms that could be improving your AI or adding some really visible effects.

You really should try to ensure that nothing gets instantiated at run time. If you really have an unavoidable case you need to minimise the number of components attached to the thing you are instantiating and add new ones after its built (because that doesn’t serialize any fields).

When you fire tracer it's every "n" rounds normally right?

–

I should add that instantiating things with meshes is particularly costly due to the creation and upload of the new meshes/textures etc.

–

Thanks a lot for that detailed answer Whydoidoit. I did actually say that my rounds are empty gameobjects so the only mesh part would be the trail, either a particle or line renderer. I would consider modelling a simple bullet for slow motion effects, but that's about it. So it looks like I'm going to have go through my code and change all the Destroy and Instantiate lines to more appropriate things. Thanks again, really helpful

–

Would just like to add, I also found this answer particularly useful: http://answers.unity3d.com/questions/196413/gameobject-pool-to-avoid-performance-issues-in-ins.html

–