Don't pause/affect particles with Time.timescale

Viewed 2065

I have a script, where on CollisionEnter2D the particles are emitted from an object and the game pauses. The particles stop too. But I don't want to pause the particles. I want them to play even when the game is paused. How can I do this?

Here is a script:

using UnityEngine;

public class MovingPlayer : MonoBehaviour
{

    public float playerSpeed;
    public float maxPos = 2.7f;

    Vector3 position;
    public uiManager ui;

    Rigidbody2D rb;

    public GameObject particleSystemPrefab;

    void Awake ()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    // Use this for initialization
    void Start ()
    {
        position = transform.position;
    }

    ......

    void OnCollisionEnter2D (Collision2D col)
    {
        if (col.gameObject.tag == "CubeObstacle") {
            foreach(ContactPoint2D contact in col.contacts)
            {
                Instantiate(particleSystemPrefab, contact.point, Quaternion.identity);
            }
            Time.timeScale = 0;
            ui.gameOverActivated();
            am.playerSound.Stop();
            PlayerPrefs.SetInt("score", score);
            PlayerPrefs.Save();
        }
    }
}
2 Answers

In the old days ParticleSystem.Simulate is used in the Update function but this was expensive. It slowed down many games.

Starting from Unity 2017.1, a new property ParticleSystem.MainModule.useUnscaledTime was added to fix this so that setting Time.timescale to 0 won't affect the particle if that's the behavior you prefer.

Simple Example:

ParticleSystem m_System = GetComponent<ParticleSystem>();
ParticleSystem.MainModule main = m_System.main;

//Use Unscaled Time
main.useUnscaledTime = true;

If you don't want to change it via code but through the Editor, it's the Delta Time drop-down option. Change it from scaled to Unscaled:

enter image description here


For your particular issue, change your OnCollisionEnter2D function to something below:

void OnCollisionEnter2D(Collision2D col)
{
    if (col.gameObject.tag == "CubeObstacle")
    {
        foreach (ContactPoint2D contact in col.contacts)
        {

            GameObject obj = Instantiate(particleSystemPrefab, contact.point, Quaternion.identity);
            ParticleSystem m_System = obj.GetComponent<ParticleSystem>();
            ParticleSystem.MainModule main = m_System.main;
            //Use Unscaled Time
            main.useUnscaledTime = true;

        }
        Time.timeScale = 0;
        ui.gameOverActivated();
        am.playerSound.Stop();
        PlayerPrefs.SetInt("score", score);
        PlayerPrefs.Save();
    }
}

Your title is a little confusing. You say "Time.timeScale = 0 don't pause particles" bu then your question says that you don't want to pause the particles when you set timeScale = 0... So I'm assuming that you want to play the particles even though you've set timeScale = 0. To have particle systems ignore timeScale, you use

particleSystem.Simulate(Time.unscaledDeltaTime, true, false);

Immediately after playing or enabling the particle system(s). https://docs.unity3d.com/ScriptReference/ParticleSystem.Simulate.html

Related