Search Issue Tracker

Won't Fix

Votes

0

Found in

2019.4

2019.4.31f1

2020.3

2021.2

2022.1

Issue ID

1383668

Regression

No

Wrong Particle is replaced by Ring Buffer Mode when a specific Particle is removed via script and Max Particles are exceeded

Visual Effects - Legacy

-

How to reproduce:
1. Open the user-submitted project
2. Open the scene "TestScene" (Assets/TestScene.unity)
3. In the Hierarchy window, select the GameObject "Particles"
4. In the Inspector window, under the script "Test", press the button "Emit particle" 7 times
5. Under "Clear at index:", press the button "0"
6. Press "Emit particle" 2 more times
7. Inspect the Scene view

Expected result: Final particle was spawned at index 0 of the Particles array
Actual result: Final particle was spawned at index 3 of the Particles array

Reproducible with: 2019.4.34f1, 2020.3.24f1, 2021.2.6f1, 2022.1.0b2

  1. Resolution Note:

    I've looked into this, but it's really unclear how to properly support removing particles via SetParticles when using ring buffer mode. This mode assumes to have full control over the particles array and makes assumptions about the layout, which can be violated if removing particles via SetParticles.

    As your system looks highly customised, would it be simpler to not use the ring buffer mode, and fully control a small list of particles via script? (Instead of calling Emit + ringbuffer mode, manipulate your own particles array to get the behaviour you want?) Then just use the Particle System for the rendering.

Comments (1)

  1. Grosnus

    Jan 22, 2022 06:06

    My response to the resolution note:

    Thank you for examining this problem. To quickly explain my use case: I was making a dynamic decal system where each decal is placed at precise position determined by whatever caused the decal to spawn. System assumes each decal can have different parameters such as lifetime, color, position, size etc. If maximum amount of decals is reached then oldest decal is replaced by newly emitted one.

    I decided to go with ParticleSystem because it handles a lot of things for me already such as z-sorting (even if multiple particles overlap on the same plane), batched mesh creation with customized attributes, fading, ring buffer and a lot more. From experience I know that often recreating such systems in managed code can lead to worse performance than Unity's internal systems so I tried to utilize ParticleSystem functionality as much as possible.

    I was afraid that because in my case a lot of particles can be spawned at quick succession invoking .SetParticles over and over will create unnecessary overhead and decided to limit usage of that method to only removal of particles, which doesn't need to happen real-time.

    The reason I wanted to remove particles in the first place is because after particles reach their lifetime they will not remove themselves from system because of ring buffer mode. That might be by design, however that is also causing ParticleSystem's culling not to properly cull the particles, because technically they still exist and they influence the bounding box, which now might be a lot bigger than it could be.

    The other problem I had was that I needed to know the last index of the particle that was just emitted because I was using SetCustomParticleData to set additional parameters per particle after emission. I was also keeping my own array of data per particle that needed to exactly reflect ParticleSystem's array.

    Knowing the issues beforehand I might've considered different solution (no ring buffer and manual control for example) however I ultimately found a workaround for the last index problem by studying when and why a particular index is being replaced and with some bookkeeping I was able to create a method that predicts last index in all cases, even after removing particles via SetParticles.

    I will email another example project that will show how I did that in case it's at all helpful.

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.