Performance question: Is it better to Instantiate particle systems OR use same particle system?
So in my game I use particle system a lot: when enemy dies or collides with player; when player collects a coin; when player receives a buff and etc.
When instantiating the particle system FPS sometimes might reduce(for a short time) from 300 to ~230. I don't know a lot about Instantiating, but through research I found out that it's pretty heavy and big companies try to avoid instantiating.
After that I also tried to increase performance: my particle systems now all have "stop action" set to "Disable" and simulation space: World.(so when I will need the same particle system it won't be tied to its last position and particles will not instantly teleport to a new location). I use following script to "instantiate" the particle systems now:
public ParticleSystem deathEffect;
public void Death()
{
deathEffect.transform.position = transform.position;
deathEffect.SetActive(true);
deathEffect.Play();
}
Now I wonder if the script I created works properly, because now "instantiating" particle systems still reduce my fps, but now from 300 to ~ 235-238. 5 FPS performance increase is not what I expected, so I hope you could help me, thanks!
Answer by oscarAbraham · Jul 11, 2021 at 02:22 AM
I can't be sure about your specific fps results without knowing more about your project, but I think I can answer the general question. Instantiating GameObjects is generally slower than reusing them, specially when they have heavy initialization calls inside them. That's not the reason why Instantiating is usually avoided, though.
Usually, the main reason for avoiding any kind of object instantiation, even plain strings, is Garbage. When an object stops being used, when there are no accessible references to them, a special mechanism from C# detects it and frees the memory that the object was using. That mechanism is called the Garbage Collector, or GC. Everything stops when the GC is cleaning stuff. In most applications, that is not a big problem, as there are lot's of dead moments that the GC can use to work; but games don't have many dead moments, so if enough Garbage accumulates, the GC will make the game stutter.
Developers avoid generating garbage by caching and reusing frequently needed objects. When the objects need to be initialized each time they are reused, we use a pattern called Object Pools. I recommend you check this, which should work well for your needs: https://learn.unity.com/tutorial/introduction-to-object-pooling
Your performance problems don't seem to be caused by the instantiation, though. That is to be expected; it's usually only a noticeable problem when creating hundreds of Objects. I guess stopping and playing again the particle system is a bit heavy. Maybe there are lots of particles at the start, with an expensive shader and/or too much blending, or collisions.
First, you should consider that fps differences can seem more dramatic than they really are when numbers are that high: The difference between 300 and 235 fps is really the difference between 3.33 and 4.25 milliseconds; it's only adding less than a millisecond per frame. If that's still concerning for you, there are lots of things that can increase particles' performance, like GPU instancing , but I'd need to know more about specific cases to make recommendations about them. It seems like a different matter.