Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Particle trail resolution?

Discussion in 'General Graphics' started by Green-Thumb-Studios, Jul 9, 2019.

  1. Green-Thumb-Studios

    Green-Thumb-Studios

    Joined:
    Nov 4, 2013
    Posts:
    143
    Heya, so I have been having a bit of an issue and I'm not how people are solving it in general.

    If you have a particle system emitting trails, the trails even at min vert distance of 0.01 still end up being clunky when moving at high speeds and not smooth in the slightest. Is there another way around this?
     
  2. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,281
    Hi, the trails are only able to drop a new point at each frame interval.

    If you go into the Time settings (Project settings), and reduce the maximum particle timestep, this will increase the accuracy of the simulation, and drop more points, but at the cost of some performance. And because this is a global setting, it will affect all Particle Systems.

    An alternative would be to call ParticleSystem.Simulate yourself from script on the system multiple times per frame to break up Time.deltaTime into smaller chunks, and set the fixedTimeStep param to false, rather than using the automatic playback, but this will cause the entire simulation to run on the main thread, which will also have performance implications.

    Neither are great solutions, but may work for you, depending on your situation :)
     
  3. Green-Thumb-Studios

    Green-Thumb-Studios

    Joined:
    Nov 4, 2013
    Posts:
    143
    Thanks for the heads up, thats a shame. I hope to find a better solution as we work through things, but ill look into the two that you provided. :) Thanks again.
     
    richardkettlewell likes this.
  4. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    505
    Did you get anywhere with this? I have very few partice system that I'd like to be utterly smooth as they are the main attraction. I'm thinking on the manual solution, but @richardkettlewell would you have a link on how to perform this ? I'm just not sure how to hook in a function on the main thread that'll update more regularly.
     
  5. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,281
    If it’s all the systems in your app, you can set the global Time option in the project settings: maximum particle timestep. Make it smaller. Watch out for performance though :)
     
  6. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    505
    Thanks for answering, it's far from being the only system in the game tough :). I tried the following, the update is correctly triggering and the rate is correct, but it does not seem to increase the resolution trails. Am I doing it wrong ?

    Code (CSharp):
    1.     [RequireComponent(typeof(ParticleSystem))]
    2.     public class ParticleSystemFixedUpdater : SimpleMonoBehaviour, IHasFixedUpdate
    3.     {
    4.         public int Rate = 10;
    5.         public bool IncludeChildSystem = true;
    6.         [ShowInInspector]
    7.         [ReadOnly]
    8.         private float CalculatedFixedDeltaRate => Time.fixedDeltaTime / Rate;
    9.         private ParticleSystem _system;
    10.         public void Awake()
    11.         {
    12.             _system = GetComponent<ParticleSystem>();
    13.         }
    14.         public void FixedUpdate()
    15.         {
    16.             var rate = CalculatedFixedDeltaRate;
    17.             for (var i = 0; i < Rate; ++i)
    18.             {
    19.                 _system.Simulate(rate, withChildren: IncludeChildSystem, restart: false, fixedTimeStep: false);
    20.             }
    21.         }
    22.     }
     
  7. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    505
    Oh .. actually it will spawn the 10 trail simulation at the same time thus position ? How could I advance, with a coroutine and unscaled time yield or rate value ?

    Like that one ?

    Code (CSharp):
    1.        
    2.      public int RatePerSeconds = 120;
    3.         public bool IncludeChildSystem = true;
    4.         [ShowInInspector]
    5.         [ReadOnly]
    6.         private float Rate => 1f/RatePerSeconds;
    7.         private ParticleSystem _system;
    8.         public void Awake()
    9.         {
    10.             _system = GetComponent<ParticleSystem>();
    11.             StartCoroutine(UpdateSimulation());
    12.         }
    13.  
    14.  
    15. private IEnumerator UpdateSimulation()
    16.         {
    17.             while (true)
    18.             {
    19.                 yield return new WaitForSecondsRealtime(Rate);
    20.                 _system.Simulate(Rate, withChildren: IncludeChildSystem, restart: false, fixedTimeStep: false);
    21.             }
    22.         }
    [Edit] : not working much either
     
    Last edited: Feb 25, 2023
  8. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,281
    I think you're on the right track. However, I think forget the coroutine and do this in Update()

    Something like:

    Code (CSharp):
    1. void Update()
    2. {
    3.     float ts = Time.timeStep;
    4.     int steps = ts / 100; // replace with something smarter
    5.     float tsPerStep = ts / steps;
    6.  
    7.     for(int i = 0; i < steps; i++)
    8.         ps.Simulate(tsPerStep, IncludeChildSystem, false, false);
    9. }
     
  9. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    505
    Thanks I'll try this in the update asap, it awfully looks like the thing I've done in the LateUpdate earlier though? So, besides the use of TimeStep, my mistake was on the FixedUpdate use instead of the Update ? I'll post my version if I get it working.
     
  10. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,281
    Hm yes sorry i missed that.. i didn't see the first of your 2 posts. Yeah your FixedUpdate code looks like it should be working.

    To confirm - your trails are dependent on the movement on the particles, and not the movement of the GameObject Transform? Because the Transform movement won't be captured at these sub-frame steps.
     
  11. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    505
    That might be the probleme indeed, they are dependent on a game object movement. However the movement is controlled by a Tween and not by physics or unity Update loop.

    So, if manually update the tween at lower intervals, the same as the particle system, would there
    be a way to say to the particle system that the transform was updated ?


    Or would, in the loop a change the to _system.transform.position be taken into account ?

    Code (CSharp):
    1. //pseudo code
    2.  
    3. //In late update
    4.   for i to nSteps UpdateTween(i)
    5.  
    6. //UpdateTween
    7.   //update _systemPosition
    8.   //Simulate particle
     
    Last edited: Mar 1, 2023
  12. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,281
    If the game object is updated in the same loop as the particle simulate, i think it should work.. i.e.

    Code (CSharp):
    1. for(...)
    2. {
    3.     gameObject.transform.position += delta;
    4.     ps.Simulate(...);
    5. }
    It's worth being aware that simulating in this way makes all the particle update code run in a blocking mode on the main thread - you lose the performance benefit of updating the particle systems on the worker threads.