Moving a ParticleSystem - why does Unity interpolate its position?

I have a particle system that emits all of its particles in an immediate burst, since it represents a bullet impact. The particle system is moved to the point of impact (by modifying its gameobject.transform.position), before ‘Emit()’ is called. The particles must not follow the emitter once they have been emitted, so the particle system is set to simulate in ‘world space’.

The problem is that particles appear in incorrect positions, particularly when the frame rate is low - it seems that the particle system interpolates the location of the emitter between its old and new positions over a number of frames, which I confirmed by adding a delay between updating the location of the particle system and the call to Emit().

Has anyone else encountered this behaviour? It seems elementary - how are we supposed to create effects like this (created with the legacy system) if this is the case?

2 Likes

Banderous,
I would need to see the code in order to figure out what’s happening with this. I do have a suggestion regarding another way to achieve the effect you are looking for, though: One of the ways that I create my OnHit weapon effects is to simply instantiate a prefab of that effect. Then it already has its position when it is created.

If you want to continue with the code you’ve written, however, I think people will need to see that code in order to determine what is going on.

Regards,
-Lance

Make sure emitter.emit is set to false. The emit property will make it emit each frame in addition the burst from Emit()

Petroz - this is in reference to the new 3.5 particle system. ParticleEmitter appears to be a component of the legacy system.

Lance2185 - Thanks for the suggestion, but instantiating a particle system for each bullet impact entails significant overhead, and each particle system uses its own draw call.

Note - and this is crucial - the problem only reproduces in low framerate situations. To reliably reproduce this on my desktop I change my ‘fixedTimestep’ in project time settings to the minimum value (0.0001).

Here’s an excerpt from the class I’m using to manager the single particle system:

public ParticleSystem explodingSystem;

public void spawnExplosion(Vector3 location, float maxRange, float damage) {
explodingSystem.transform.position = location;
explodingSystem.Emit(20);

}

Pretty simple. I will try and put together a unity package that reproduces the problem.

911071–34128–$repro.unitypackage (11.7 KB)

I’ve also run into issues with particle bursts when using Time.captureFramerate - particles firing in the wrong position and direction - which didn’t happen without it. Possibly related?

d.eisenga - yes, most certainly. I wasn’t aware of Time.captureFramerate as a way to lock framerate, otherwise I’d have used it in my repro.

FYI Unity have accepted this as a bug - 461698.

I’m having exactly the same problem, have been googling all day for solutions!

Can’t believe more people aren’t complaining about this?

That was my reaction, and it’s why I was hesitant to raise it as a bug straight away. Moving a single particle system is key to getting a lot of particles on screen at a decent frame rate, I don’t know how else one would do bullet impact effects. I guess people haven’t migrated from the old particle system, but still.

I’m finding that virtually any effect using world space is screwy. Even instantiating an effect and immediately moving it (so in effect this happens in zero time) and playing it manually will still cause this odd interpolation.

Having the same problem here with the interpolated particle system ! Lower frame rate makes this even worse. Its makes creating this effect impossible on iOS while keeping good performance. Unity please fix this interpolation issue!

We just came up with a workaround for this problem on one of our upcoming iOS-titles.

ps.transform.position = new Vector3(0, 100, 0);
ps.Simulate(0.005f, true);
ps.Play(true);

We haven’t really experimented with how short you can simulate, but so far it works great for us!

2 Likes

Papatsu, thanks for your workaround, it’s helped me with my problem.

For reference here’s the issue in detail:
I have a grid of GameObjects - basically, think the invaders of space invaders. They are moved left to right in discrete timed chunks, rather than smoothly animated. The Invader prefab has a ParticleSystem on it, which is set to go off when the invader dies.

What happens however is that in local space it’s fine, but in world space it seems not to work at all, although on closer inspection you can sometimes - sometimes - see a few errant particles. The lack of the whole system in all its glory is very confusing; I can’t tell if the system is out of position, hugley scaled up, or misfiring in some other way.

If I click the invader in the scene view and press the ‘Simulate’ button in the Particle Effect dialogue box, the same thing happens (usually nothing, occasionally something very wrong). On the second press however, it works. Perfectly. Again, in local space all of this behaves as expected, first time.

Using Papatsu’s trick of simulating it slightly first has fixed the problem for me.

As an alternative to using Simulate(0.005f), this works for me if you need to move the system multiple times in one function call

Note: set the particle system to use WORLD space.

ParticleSystem system;
Vector3  position = Vector3.zero;

while(true)
{
   position.x += 10;
   system.transform.localPosition = position;
   system.gameObject.SetActiveRecursively(false);
   system.gameObject.SetActiveRecursively(true);
   system.Play(true);

   yield return new WaitForEndOfFrame();
}

You still get a slight delay between bursts while unity WaitForEndOfFrame executes.

This bug is still present in 4.0.0.f5. And in Flash, the workaround doesn’t work around. Any news on this getting fixed?

This was clearly never fixed, yet the bug I raised was closed as fixed with the comment:

“The issue has been fixed and therefore the case has been closed”

In fact I have already tried to reopen it once having found that it isn’t fixed, I’ll try to reopen it again.

Still happening to me on 3.5.6f4

		if (m_particlePool.Count == 0) {
			particle = Instantiate(m_coinSplashParticle, new Vector3(pos.x, m_particleYPos.position.y, pos.z), Quaternion.Euler(270f, 0f, 0f)) as CoinSplashParticle;
		} else {
			particle = m_particlePool.Dequeue();
			particle._t.position = new Vector3(pos.x, m_particleYPos.position.y, pos.z);
		}
		yield return new WaitForEndOfFrame();
		particle._particle.Play();

If the particle comes from the pool it will play halfway between the old and new position =
The interpolation bug seems to be the culprit if I had to guess.

I thought maybe yielding until the end of frame would fix it but it doesn’t. I also tried yielding for a whole second and it still doesn’t play in the right position. The simulate() workaround did the trick though.

I am trying to recycle my particles. I have one sub emitter set to world space. I SetActive(false) on the entire hierarchy. When I want to reuse the particle system, I move the particle system to it’s new starting position, and then call SetActive(true). I then see a streak across my screen because it is interpolating between the sub emitters old position and new position.

Why is the bug closed?

I had this problem if I used Play(); and Stop(); but using enableEmission = true/false rectified it.

Still broken on 4.2. I’m sure they’ll get to it in 5. They need to give us a reason to upgrade right? It’s the Adobe model of software updates. :wink:

Simulate(0.0001f) hack works for me.