How can I play a particle system only when it’s visible?

How can I play a particle system only when it’s visible?

I am making a game and it has a lot of particle systems in it as special effects, and all of them are supposed to be playing at the same time, but doing that will be heavy on the game's performance, then I thought:
Is it possible to play a particle system only when it is visible to the camera and stop playing it when it is out of range or hidden from the camera, maybe with physics raycasting? If it is, can someone help me to write codes that will do so.


Answer 1:

There are two Unity event methods you can implement for this purpose: OnBecameVisible() and OnBecameInvisible(). You can use that to pause and unpause the particle system on the same GameObject.

This doesn’t use raycasting but instead hooks into the frustum culling and occlusion culling system of the engine which determines the visibility of all game objects anyway.

Answer 2:

Note that Unity already does a form of this on its own for frustum culling of particle systems (it’s more efficient for systems that can be efficiently predicted – see this article for a detailed breakdown)

On the particle system’s main module, you’ll see a “Culling Mode” dropdown. As described in the Unity docs:

Culling Mode Choose whether to pause Particle System simulation when particles are offscreen. Culling when offscreen is most efficient, but you may want to continue simulation for off-one effects.

  • Automatic Looping systems use Pause, and all other system use Always Simulate.

  • Pause And Catch-up The system stops simulating while offscreen. When re-entering the view, the simulation performs a large step to reach the point where it would have been had it not paused. In complex systems, this option can cause performance spikes.

  • Pause The system stops simulating while offscreen.

  • Always Simulate The system processes its simulation on each frame, regardless of whether it is on screen or not. This can be useful for one-shot effects such as fireworks, where during the simulation would be obvious.

So far as I’m aware, this applies only to frustum culling (ie. determining whether or not the particle system’s bounds overlap with the camera’s view frustum). It does not necessarily cull/pause particle systems that are occluded behind walls or other barriers, so a custom solution may be needed for that case.

You can use Unity’s Culling Groups to have more explicit control over culling, as demonstrated for particle systems here.