Legacy Documentation: Version 2018.2 (Go to current version)
  • C#


Suggest a change


Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.


Submission failed

For some reason your suggested change could not be submitted. Please <a>try again</a> in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.



Switch to Manual
public bool automaticCullingEnabled;


Does this system support Automatic Culling?

Internally, each Particle System has 2 modes of operating: procedural and non-procedural.

In procedural mode, it is possible to know the state of a Particle System for any point in time (past and future) whereas a non-procedural system is unpredictable. This means that it is possible to quickly fast forward (and rewind) a procedural system to any point in time.

When a system goes out of the view of any camera, it is culled. When this occurs, the procedural system stops updating. It will efficiently fast forward to the new point in time when the system becomes visible again. A non-procedural system cannot do this, so it must continue updating itself even when offscreen, due to its unpredictable nature.

In order to support Automatic Culling, you can only use a subset of the Particle System modules and properties. For example, using the Limit Velocity over Lifetime module will disable Automatic Culling. Additionally, modifying any properties from script whilst the system is playing will also disable Automatic Culling.

To discover if you are using any properties that disable this feature, a small speech bubble appears in the upper right corner of the Inspector. The tooltip for this icon gives you details about why Automatic Culling is disabled.

using UnityEngine;

public class CustomParticleCulling : MonoBehaviour { public float cullingRadius = 10.0f; public ParticleSystem target;

private CullingGroup m_CullingGroup;

void Start () { if (target.automaticCullingEnabled) { enabled = false; return }

m_CullingGroup = new CullingGroup(); m_CullingGroup.targetCamera = Camera.main; m_CullingGroup.SetBoundingSpheres(new BoundingSphere[] { new BoundingSphere(transform.position, cullingRadius) }); m_CullingGroup.SetBoundingSphereCount(1); m_CullingGroup.onStateChanged += OnStateChanged; }

void OnStateChanged(CullingGroupEvent sphere) { if (sphere.isVisible) { // We could simulate forward a little here to hide that the system was not updated off-screen. target.Play(true); } else { target.Pause(); } }

void OnDestroy() { if(m_CullingGroup != null) m_CullingGroup.Dispose(); }

void OnDrawGizmos() { // Draw gizmos to show the culling sphere. Gizmos.color = Color.yellow; Gizmos.DrawWireSphere(transform.position, cullingRadius); } }

Did you find this page useful? Please give it a rating: