FAQ

Here you’ll find some of the frequently asked questions of Particle Playground.

I'm new to Particle Playground, how do I get started?

Watch the Video Guides, they cover the very basics of Particle Playground. The Script Reference section also has a short introduction.

I own Particle Playground 2, will my license work for Particle Playground 3?

Yes, with no additional costs.

Is Particle Playground 3 backwards compatible with previous versions?

Yes, you will be able to run your particle systems in the upgraded framework along with increased performance. For safety reasons remember to make a backup of your existing project before installing Particle Playground 3 over a previous version.

Is Particle Playground compatible with 2D?

Yes! A Particle Playground system can collide, project and paint using 2D colliders. There’s layer sorting functionality directly exposed in Inspector. You can also disable any velocity axis to ensure that particles stay at the desired depth.

Is Particle Playground compatible with the Unity GUI?

A Particle Playground system has the very same compatibility as the Shuriken particle system, where if you want to render the particles on the UI layer you need to set the Canvas to render in World Space.

A particle system cannot use a Sprite natively as emission source, you would have to use a separate texture in the Source: State mode.

You can use a RectTransform as an emission source.

Is Particle Playground compatible with Unity 5?

Yes!

Is Particle Playground compatible with the updated Shuriken in Unity 5.3?

Yes!

What does the Playground Manager do?

The Playground Manager will instantiate along with a Particle Playground system. The Manager is running all particle systems in your scene, contain all the Global Manipulators and has extensive settings for how multithreading should behave.

In script the Playground Manager is the PlaygroundC class, which has a set of wrapper functions for creating, getting and setting Playground related content. Please see the Scripting Reference for further details.

There should always only be one instance of the Playground Manager in your scene. When making a particle system to a prefab, make sure you don’t include the Playground Manager.

Do the particle systems need to be under the Playground Manager in Hierarchy?

No, feel free to have any setup you prefer in the Hierarchy view. A Particle Playground system will automatically be parented to the Playground Manager for convenience. Should you not want this behavior it can be toggled through Playground Manager > Advanced > Group Automatically.

How do I scale an entire particle system?

Assign the script ParticleSystemScaler.cs found in the Simple Scripts folder to the Particle Playground system you wish to scale. This will let you automatically scale all particle Size, Velocity, Overflow Offset, Source Scatter and Lifetime Positioning. Note that Source positions won’t be scaled.

If you want the script to scale in Editor then uncomment line 9:

[ExecuteInEditMode()]

How do I emit particles from script?

To make a Particle Playground system emit particles manually from script, where you for example determine the position, velocity, lifetime and color can be done like this:

using UnityEngine;
using System.Collections;
using ParticlePlayground;

public class EmitExample : MonoBehaviour {
    IEnumerator Start () {
        PlaygroundParticlesC particles = GetComponent<PlaygroundParticlesC>();
        Vector3 position = Vector3.zero;
        Vector3 velocity = Vector3.up;
        float lifetime = 10f;
        Color32 color = Color.white;

        while (!particles.IsReady())
            yield return null;

        particles.Emit (positionvelocitylifetimecolor);
    }
}

There are several overloads for emitting particles. Using any of these will make a particle system automatically go into Source: Script mode.

Remember that you should always wait for the particle system to become ready, that can be checked by using IsReady().

I don't see any particles when calling Emit() through script, what could be wrong?

First make sure that you supply a color which is not fully transparent or goes inline with your particle shader (for example a bright color in an additive shader or a dark color in a multiplicative shader).

Sometimes you need to wait for the particle system to become ready before you call for emission, for example:

using UnityEngine;
using System.Collections;
using ParticlePlayground;

public class WaitBeforeReady : MonoBehaviour {

    public PlaygroundParticlesC particles;

    IEnumerator Start () {

        // Wait for particle system to become ready...
        while (!particles.IsReady())
            yield return null;

        // ...then emit!
        particles.Emit ();
    }
}

How do I start/stop emission from script?

To make a particle system start or stop its emission you can either call:

PlaygroundParticlesC particles = GetComponent<PlaygroundParticlesC>();
particles.emit = bool;

or

particles.Emit(bool);

The difference is that calling Emit(true) will restart the particle system if emission is currently going.

The latter example is not to be confused with Source: Script emission and the other Emit() overloads. Emit(bool) will turn emission on and off, Emit() will emit a particle. Using Emit(bool) is only available for the non-scripted sources and will not have any effect when using Source: Script.

How do I wait until a particle system has initialized all caches and is ready for simulation?

Sometimes you need to wait for a particle system to boot up, for instance before activating a GameObject or enabling a component. This can be done by waiting until IsReady() returns true. Example:

IEnumerator Start () {
    PlaygroundParticlesC particles = GetComponent<PlaygroundParticlesC>();
    while (!particles.IsReady())
        yield return null;
}

My emitter (Source) is moving and particles are too far apart, how can I solve that?

When a particle system’s emitter is moving you will experience different density of particle distribution depending on the emitter’s movement speed. To solve this you can use Advanced > Simulation Space: Local, this will move all particles along with the particle system while using Movement Compensation. Use Compensation Lifetime Strength to transition between Local to World simulation behavior. This enables you to for example ensure that particles moves with your Source, but give the distribution some slack at specified lifetime.

Keep in mind that the Source methods is handling the local simulation space differently to cope with positions and rotations. This can require that you change the Hierarchy structure depending on your selected Source.

If you want to simulate your particle system in world space, but ensure a constant particle distribution with even spacings you can use the script EmitOnTranslation.cs.

How do I control Particle Playground with PlayMaker?

Currently there are no ready-made PlayMaker actions available. You can however drag the Playground Particles C (Script) component in Inspector to the PlayMaker State window, where Get- and Set Property can be chosen. This ables you to reach into all public members of Particle Playground with PlayMaker thanks to the way PlayMaker uses reflection.

How do I create controlled particle flows?

There are several options to create highly controllable particle flows. The method depends on the result you’re after.

  • Forces > Force Annihilation > Lifetime Positioning and set positions over the particles lifetime by Animation Curves. This will make particles to not be influenced by any forces.
  • Forces > Lifetime Velocity will add velocity by Animation Curves over the particles lifetime.
  • Manipulators:
    • Attractor – Draw particles in range toward a point in world space.
    • Attractor Gravitational – Draw particles in range toward a point in world space by gravity.
    • Vortex – Draw particles in range toward a point in world space through a spinning vortex.
    • Repellent – Move particles in range away from a point in world space.
    • Properties:
      • Target – Move particles in range over time toward Transforms.
      • Mesh Target – Move particles in range over time toward mesh vertices.
      • Skinned Mesh Target – Move particles in range over time toward a skinned mesh vertices.
      • State Target – Move particles in range over time toward pixels.
      • Spline Target – Move particles in range over time towards a spline using either particle- or spline time.
      • Math – Move particles in range over time using common math algorithms.
  • Playground Spline – Move all particles with the spline’s time offset. This requires that you use Only Source Positions, Lifetime Positioning or Transition Back To Source.

How do I remove the "P" icon from a particle system in Scene View?

At the very top of the Inspector you can click the P icon and select None.

Where can I find more particle system effects?

Through Extend Your Playground. You’ll also find additional particle system examples in the Example Project which comes with the installation.

How do I export an effect for sharing or redistributing?

First the particle system should be made into a Preset. Create a Preset by clicking Create Preset in the particle system’s Inspector. Next use the Preset Wizard’s Publish mode to export your particle system(s) as a UnityPackage. Only the core framework will be included – which is free to share or redistribute in any means you’d like.

For further details please see the Publishing Guide.

How do I change the Project path to the Particle Playground assets?

If you have restructured where the Particle Playground folder is placed in your Project View you need to set the new path in Window > Particle Playground > Settings > Paths > Playground Path.

Note that if you should have a very large project, you may want to change the static path to your Playground Settings.asset in Scripts/Editor/PlaygroundSettingsC.cs by variable settingsPath. Example:

public static string settingsPath = "New location/Particle Playground/Playground Assets/Settings/Playground Settings.asset";

This will prevent Particle Playground from searching for the settings file which may slow down the Editor between Play/Stop sessions or when opening the Playground Wizard in large projects.

I don't see any particles on iOS 64-bit (IL2CPP), what do I do?

If you’re using the Scripting Backend: IL2CPP in Unity 4.6 there’s no support for multithreading on iOS. You must use either a later version of Unity or Scripting Backend: Mono (2x).

What does the Overflow Offset setting do?

Overflow Offset (found in Particle Settings > Overflow Offset) will offset the Particle Count by the remainder of the created Source points. This can be used to create directional patterns, for example runway lights.

Nothing happens when I try to create a State using a texture, what could be wrong?

Make sure your texture is set to Read/Write Enabled in its Import Settings.
If you are changing the texture, press the “Refresh” button next to your State’s settings.

Keep in mind that the texture’s pixels is measured in units (1 pixel = 1 unit), you often need to set the Scale value low.

How do I see all pixels in a Source: State texture?

The State source with a texture assigned will create particle birth positions from each pixel in the texture (where full scale is 1 pixel/unit). If you don’t see all pixels this means that the Particle Count is lower than the pixels in the image.

To mend this click Set Particle Count on your unfolded State in Inspector, or set the Particle Settings > Particle Count manually.

Tip: Always try to keep the texture resolution as low as possible for performance reasons.

I have set a new texture or mesh to a State, how do I refresh it through script?

A Particle Playground system has a list of States which you can toggle in between. To rebuild a specified State’s cache you can call:

PlaygroundParticlesC particles = GetComponent<PlaygroundParticlesC>();
particles.states[0].Initialize();

Where [0] means the first State in the list.

I'm changing Particle Count over time, why is my particle system restarting?

A Particle Playground system is caching all particles and correlated properties for performance reasons during simulation. When you change Particle Count the cache will need to be rebuilt and new Lifetime Sorting timings will be set.

Instead to increase or decrease particles over time you can use the Particle Mask. Example:

using UnityEngine;
using System.Collections;
using ParticlePlayground;

public class ParticleMask : MonoBehaviour {
    
    public float mask = 0f// 1.0f means full masking
    public PlaygroundParticlesC particles;
    
    void Start () {
        if (particles == null)
            particles = GetComponent<PlaygroundParticlesC>();
        particles.applyParticleMask = true;
        UpdateMask();
    }
    
    void Update () {
        UpdateMask();
    }
    
    void UpdateMask () {
        mask = Mathf.Clamp01(mask);
        particles.particleMask = Mathf.RoundToInt(particles.particleCount*mask);
    }
}

How do I create a new Manipulator through script?

The Manipulators has the class ManipulatorObjectC, where if you want to create a new Global- or Local Manipulator there’s wrapper functions in the PlaygroundC class. Example:

using UnityEngine;
using System.Collections;
using ParticlePlayground;

public class AddGlobalOrLocalManipulator : MonoBehaviour {
    
    public PlaygroundParticlesC particles;
    
    void Start () {
        
        // Add a Global Manipulator
        ManipulatorObjectC globalManipulator = PlaygroundC.ManipulatorObject(transform);
        
        // Add a Local Manipulator
        ManipulatorObjectC localManipulator = PlaygroundC.ManipulatorObject(transformparticles);
    }
}

How do I pool my particle systems for reuse?

There’s a script called SwitchCachedParticleSystemC.cs found in the Simple Scripts folder. This will let you instantiate a particle system by quantity where you simply could call EnableParticleSystem for enabling the next in queue:

EnableParticleSystem (Vector3);

How do I prewarm a particle system?

You can start a particle system at any cycle of its lifetime by enabling Advanced > On Enable > Prewarm. The Prewarm Lifetime Cycles will determine which time it should scrub to and the Prewarm Cycles (Resolution) determines the calculated iterations. A higher resolution means more accurate velocities but will require more CPU at particle system boot.

How do I pause a particle system?

Set the Advanced > Time Scale to 0. Through script you can call:

particles.particleTimescale = 0;

Particle movement or UV animation appears jittery / jumpy, how do I fix that?

Usually this behavior can be seen on heavier setup particle systems.

The Particle Playground systems are calculated asynchronously on another thread (where available), separate from the main-thread where the overall game loop (MonoBehavior) lives. This makes the determination uncertain when a calculation loop has finished, it could be this or next frame. When calculation is stepped through the particle positions, colors, sizes and timings will be updated immediately unless specified.

This update can be synced onto the main-thread to ensure a stable presentation. Do this by enabling Advanced > Misc > Sync Particles To Main-Thread.

How do I emit several particles upon an Event?

To have highly customizable emission when particles are broadcasting an Event use Event Listeners. Set your birth, death, collision or timed event to Broadcast Type: EventListeners or Both, then use an event listener through script. Example:

using UnityEngine;
using System.Collections;
using ParticlePlayground;

public class MultiEmitOnEvent : MonoBehaviour {
    
    public PlaygroundParticlesC particlesEvent;                    // The event particle system
    public PlaygroundParticlesC particlesEmit;                    // The emission particle system
    public int emitCount = 8;                                    // The amount of particles
    public Vector3 randomVelocityMin = new Vector3(-1f,0,-1f);    // The minimum random velocity
    public Vector3 randomVelocityMax = new Vector3(1f,1f,1f);    // The maximum random velocity
    public Color32 color = Color.white;                            // The color of particles
    
    void Start () {
        
        // Specify which event you would like to listen to
        PlaygroundC.GetEvent (0particlesEvent).particleEvent += EmitOnEvent;
    }

    // EmitOnEvent will be called when condition in your Event is met 
    void EmitOnEvent (PlaygroundEventParticle particle) {
        particlesEmit.Emit (emitCountparticle.collisionParticlePositionrandomVelocityMinrandomVelocityMaxcolor);
    }
}

How do I let GameObjects follow my particles?

If you want a ready solution with pooling which is multithreading friendly –  where each GameObject will be paired with a particle you can use the script PlaygroundFollow.cs. There’s also an example scene called Follow Particle (Trail Renderers).

If you want to know where a certain particle by id is you can use:

particles.GetParticlePosition(int);

How can I change Lifetime Color during runtime?

A Particle Playground system uses gradients for coloring its particles when using Color Source: Lifetime Color (or Source when no source color information is available). Example to change gradient during runtime:

using UnityEngine;
using ParticlePlayground;
public class ChangeLifetimeGradient : MonoBehaviour {
    
    public PlaygroundParticlesC particles;
    public Gradient newGradient;
    
    void Start () {
        particles.lifetimeColor = newGradient;
    }
}

Example to change a specific color in the current gradient:

using UnityEngine;
using ParticlePlayground;

public class ChangeLifetimeGradient : MonoBehaviour {
    
    public PlaygroundParticlesC particles;
    public Color newEndColor;
    
    void Start () {
        
        // Get the colorand alpha keys of the current lifetime gradient
        GradientColorKey[] newLifetimeColorKeys = (GradientColorKey[])particles.lifetimeColor.colorKeys.Clone();
        GradientAlphaKey[] newLifetimeAlphaKeys = (GradientAlphaKey[])particles.lifetimeColor.alphaKeys.Clone();
        
        // Apply the new end color
        newLifetimeColorKeys[newLifetimeColorKeys.Length-1].color = newEndColor;
        
        // Set the colorand alpha keys back into the lifetime gradient
        particles.lifetimeColor.SetKeys(newLifetimeColorKeysnewLifetimeAlphaKeys);
    }
}

How do I change Turbulence Strength over time?

Example how to change Turbulence Strength over time:

using UnityEngine;
using ParticlePlayground;

public class IncreaseTurbulenceOverTime : MonoBehaviour {

    public PlaygroundParticlesC particles;
    public float maxTurbulence = 20f;
    public float increaseSpeed = 1f;

    void Update () {
        if (particles.turbulenceStrength < maxTurbulence)
            particles.turbulenceStrength += increaseSpeed*Time.deltaTime;
    }
}

Certain particle systems takes a couple of frames to start emitting, why is that?

The initialization will take longer depending on how much particles should be cached. As the caching is multithreaded for performance the natural behavior is to become available later, rather than making the main-thread freeze while booting up. When using Lifetime Sorting: Nearest Neighbor or Prewarm you may experience additional frames before activation. 

To get around this you have a couple of options depending on your particle system’s behavior:

  • Let the particle system initialize before you need it.
  • Don’t instantiate the particle system in the middle of runtime, but rather let it activate when it is needed.
  • Use Source: Script mode to call for controlled emission, this will annihilate any potential waiting times.

I experience particles being one frame behind with Skinned World Objects and Only Source Positions, can I fix that?

Yes! If particles must follow the exact vertex positions on your skinned mesh while it moves then enable Source > Force Update On Main-Thread.

This is because the skinned mesh vertex positioning is done asynchronously while particle update on screen is done after the calculation loop has finished. Using Force Update On Main-Thread will ensure the update happens this frame, but with a natural performance penalty.

How could I know where a certain particle is by its id while debugging?

You can use gizmo labels to see where a particle with certain particle id is. For example:

using UnityEngine;
using ParticlePlayground;

[ExecuteInEditMode()]
public class ShowParticleIndex : MonoBehaviour {
    
    public Vector3 labelOffset = new Vector3(0, .5f0);
    public PlaygroundParticlesC particles;
    
    void OnEnable () {
        if (particles==null)
            particles = GetComponent<PlaygroundParticlesC>();
    }
    
    #if UNITY_EDITOR
    void OnDrawGizmos () {
        if (particles!=null)
        for (int i = 0i<particles.particleCounti++) {
            UnityEditor.Handles.Label (particles.playgroundCache.position[i]+labelOffseti.ToString());
        }
    }
    #endif
}

I'm creating extensive particle behaviors, where can I get all particle info?

All particles are stored in a variable called particleCache on a Particle Playground system which is of type ParticleSystem.Particle[]. All the behavior properties, for example if they have been influenced by a Manipulator can be reached through the playgroundCache. The playgroundCache is of type PlaygroundCache, where you’ll find built-in arrays for all particle properties.

Basic example:

IEnumerator Start () {
    PlaygroundParticlesC particles = GetComponent<PlaygroundParticlesC>();
    while (!particles.IsReady())
        yield return null;

    // Reach into the Source Scatter and remove scattering for particle id 10
    particles.playgroundCache.scatterPosition[10] = Vector3.zero;
}

I have a very strict GC allocation budget, what should I think about?

Most functionality of Particle Playground’s particles involves working with caches and will not allocate any GC (Garbage Collection), however each calculation thread call will require around 360 bytes of GC allocation.

  • By setting Playground Manager > Advanced > Multithreading > Particle Thread Method to OneForAll, the Turbulence Thread Method and Skinned Mesh Thread Method to InsideParticleCalculation, you will lower the GC allocations drastically on multi core platforms.
  • When emitting from procedural meshes the GC allocations will be depending on the amount of vertices that is updated.
  • Try to reuse your frequently appearing particle systems and only instantiate them when the scene loads, you could make use of the SwitchCachedParticleSystemC.cs script which tags along the installation.

I want even space between particles, how do I get that?

If you want to emit particles at a constant rate having the same space between them enable Advanced > Rebirth Options > Delta Position Adjustment. Make sure you’re also using a Linear method of Lifetime Sorting.

If your Source is moving then you could use the EmitOnTranslation.cs script found in the Simple Scripts folder.

I want to translate (move) all particles manually, how could I do that?

A Particle Playground system has some functions ready so you don’t have to dig into the playgroundCache. For example the public Translate function:

using UnityEngine;
using ParticlePlayground;

/// <summary>
/// Move all particles in a particle systemEnable multithreading to run the translation asynchronously on another thread.
/// </summary>
[ExecuteInEditMode()]
public class TranslateParticles : MonoBehaviour {
    
    public PlaygroundParticlesC particles;
    public Vector3 translation;
    public bool multithreading;
    
    void Update () {
        if (particles==nullreturn;
        if (multithreading) {
            PlaygroundC.RunAsync(()=>{
                Translate();
            });
        } else Translate();
    }
    
    void Translate () {
        for (int i = 0i<particles.particleCounti++)
            particles.Translate (itranslation*PlaygroundC.globalDeltaTime);
    }
}

Is there any way to automatically convert a Shuriken particle system into a Particle Playground system?

No. The systems are too far apart in their functionality which makes it nearly impossible to automatically convert particle systems in between. However converting a particle system manually is often a quick task.

How do I script toward the Playground Spline?

See the Playground Spline page for scripting examples.

How do I emit with spherical velocity from script?

To emit spherically from script you can either use the method of the Playground Circle Shot preset which simply rotates its Transform or by using this example:

using UnityEngine;
using System.Collections;
using ParticlePlayground;

public class CircleEmit : MonoBehaviour {

    public float velocity = 1f;
    public Color color = Color.white;
    public float width = 1f;
    public float height = 1f;

    IEnumerator Start () {
        PlaygroundParticlesC particles = GetComponent<PlaygroundParticlesC>();
        while (!particles.IsReady())
            yield return null;

        Vector3 position = particles.particleSystemTransform.position;
        for (int i = 0i<particles.particleCounti++) {
            float iCircle = 360f*((i*1f)/(particles.particleCount*1f));
            Vector3 direction = new Vector3(Mathf.Cos(Mathf.Deg2Rad*iCircle)*widthMathf.Sin(Mathf.Deg2Rad*iCircle)*height0);
            particles.Emit (positiondirection*velocitycolor);
        }
    }
}

Can I make use of Playground's multithreading for custom use?

Yes! It’s actually really straightforward. You can use a lambda expression to run your code as an action through PlaygroundC.RunAsync(). Here’s an example:

using UnityEngine;
using ParticlePlayground;

public class RunMultithreaded : MonoBehaviour {

    void Start () {
        PlaygroundC.RunAsync(() => {
            Debug.Log ("Asynchronous hello from another thread.");
        });
        Debug.Log ("This line will potentially run before RunAsync is done.");
    }
}

Remember these key approaches:

  • Unity is not thread-safe so you cannot have any native Unity objects run on another thread, such as the Physics-, GameObject- or Transform class. Instead you need to separate calculations from actual affect, where you can use wrapper classes to work with Unity objects.
  • You will never know when an asynchronous call is finished unless having a check implemented, example:
using UnityEngine;
using System.Collections;
using ParticlePlayground;

public class RunMultithreaded : MonoBehaviour {

    bool threadIsDone = true;

    void Update () {
        StartCoroutine(RunSomethingAsynchronously());
    }

    IEnumerator RunSomethingAsynchronously () {
        if (!threadIsDone
            yield break;

        threadIsDone = false;

        PlaygroundC.RunAsync(() => {

            /********************************
             * Heavy calculations goes here * 
             ********************************/

            threadIsDone = true;
        });

        while (!threadIsDone)
            yield return null;

        Debug.Log ("Thread is finished.");
    }
}

My question isn't here, where do I turn?

Welcome to join the Particle Playground user group or the Unity forum thread to ask your questions there.