Erratic Behaviour for ParticleSystem.Simulation with Start Delay

Not sure if this is a bug, or if this is most suitable for the graphics section, but it has to do with the particle system, so…

I’m using the following:

particleSystem.Simulate(someValue, false, true, false);

The particle system should always end up at the state of someValue, which is why I have the restart parameter set to true. This works fine if there’s no start delay on the particle system, and I get a 1:1 match with the preview in Unity using the little playback control window for particles:

3502041--279205--upload_2018-5-18_16-41-36.png

But things get weird if I add a start delay to the particle system. If I set the delay to 0.5, the particle shows up at 1.0. If I set it to 0.8, it shows up at 1.6. If I set it to 1, it shows up at 2… and sometimes it just dissapears immediately after that. This is only when using Simulate. If I run the effect in the editor using the built-in playback controls, it’s fine.

If I do this:

particleSystem.Stop(false, ParticleSystemStopBehavior.StopEmittingAndClear);
particleSystem.Play(false);
particleSystem.Simulate(someValue, false, false, false);

The problem goes away.
If I set the restart parameter to true, even with the extra two lines, the problem comes back.

It also only happens if the particle system is NOT looping.

Is this normal, or a bug? Has it been fixed in some version of Unity? I’m currently on 2018.1.0b13.

EDIT:

Tested with Unity 2018.2.0b2. It’s still there.

EDIT 2:

So upon further digging while trying workarounds, I found out that ParticleSystem.time returns the playback time not including the delay, but the getter requires a playback time INCLUDING the delay. So if you set the playback time to 1.0, then retrieve it with a random start delay, you’ll get some incoherent value that can’t be traced because there’s no way I know of to get the internal random start delay for the system (which isn’t per-particle, it’s for the system).

This is avoidable with non-random start delays, but I can’t figure out how to deal with this if the delay is randomized because nothing from particleSystem.main.startDelay reports the actual internal value.

This is really confusing and not documented! If I set the playback to a value and then use the getter immediately after, I expect that I should get that same value. The playback window’s Playback Time field works the way it should and doesn’t randomly change the playback based on the start delay. I think it should be the same for ParticleSystem.time.

EDIT 3:

Enabling prewarm turns up the weirdness to 11.
Here’s what I see in the editor if I restart the system using the playback window and let it simulate to 0.5:

Here’s what I see when I render this out with Simulate to 0.5:

At no noticeable point when previewing the system using the playback window do I see the pattern of the second image. Random seed is fixed. I get the same two results every time.

On that note, scrubbing Playback Time and prewarm using the playback window doesn’t work. I have to hit restart and let it play. If I try to scrub, the prewarm particles disappear.

Here’s a video:

@karl_jones @richardkettlewell

Can you guys chime in, please? I’m working on updating one my particle tools using Unity 2018.1 and I’m running into some trouble. I’m hoping I’m just overlooking something obvious so I don’t have to wait for a bug fix. Thanks!

It’s possible to query the random
Start Delay that has actually been used for the particle system, but it’s undocumented because it’s a bit of a trick, rather than being exposed in a nice way.

It’s something like:

float t = ps.main.startDelay.Evaluate(0.0f, ps.main.randomSeed);

Apologies if I got that wrong… nowhere near my work computer right now… should be pretty close at least :wink:

Let me know if you need more help.

2 Likes

Thanks so much for the quick response. I really appreciate it. :slight_smile:

I don’t think I would’ve figured out I needed to pass the random seed to a ps curve’s Evaluate.
What I ended up doing was storing a seperate float for the playback time myself and resimulating the entire system.

This way, although it can be costly for complex, non-determinate systems, it avoids all the issues (including the prewarm particle issue with the built-in playback window). I think my tool is almost finished now!

P.S.

  • Love the all the new particle system features you guys have been adding since ~5.3.
2 Likes

Hi Mirza, I’ve been investigating this myself today. I can’t seem to get to the solution you propose. We have a ParticleSystem with various children (who also have children). A couple of these children have delays and they seem to reset no matter what I do. I have tried Parent.Simulate(targetTime, true, true, false); I have also tried Simulating them individually, removing start delays and simulating if necessary, etc. etc.

Even if I do a simple Pause(true); and Play(true) on the Parent, it resets each child ParticleSystem that has a delay (unless its already playing). Sure would be fantastic to have .Simulate take the delays into account.

You can even see this in unity preview as you pointed out.