Monday, November 7, 2016

Unity: Shuriken particles do not randomize

There's an issue with some versions of Unity where particles that should render with some random parameters instead render exactly the same every time. For instance, when setting the size to "Random Between 2 Constants", you'll see that each particle does have a random size; however, when playing this particle multiple times, that size will be the same on each play.

Some later versions of Unity have fixed this; however, if you're seeing this problem but don't want to or can't upgrade for whatever reason, there is a manual solution: set the random seed the particle system uses before playing the particle. Add this line before manually playing your particle system:

particleSystem.randomSeed = (uint)Random.Range(0,9999999);

particleSystem is the name of variable representing your particle system.

Here is a full script that will find a ParticleSystem attached to the GameObject the script is attached to, set the seed, and play the particle. If you set the "destroyAfterPlay" bool to True, it will also destroy the GameObject after playing -- this is useful for instantiating lots of particles and being assured they'll be cleaned up properly.

using UnityEngine;

public class ParticleController : MonoBehaviour
{
    // Find, play, and destroy an attached particle system.
    private ParticleSystem particleSystem;
    private bool startDestructionProcess = false;
    public bool destroyAfterPlay = false;

    void Start ()
    {
        // Find the attached particle system.
        particleSystem = this.gameObject.GetComponent<ParticleSystem>();

        // If we find it, set the seed and play it.
        if (particleSystem)
        {
            particleSystem.randomSeed = (uint)Random.Range(0, 9999999);
            particleSystem.Play();

            // Flag that this particle can be destroyed after it stops playing.
            startDestructionProcess = true;
        }
    }
  
    void Update ()
    {
        if (startDestructionProcess && destroyAfterPlay)
        {
            if (!particleSystem.isPlaying || !particleSystem)
            {
                // The particle system is done playing and we've flagged we want it destroyed.
                Destroy(this.gameObject);
            }
        }
    }
}

No comments:

Post a Comment