Search Unity

how to make ColorOverLifetime only affect new particles?

Discussion in 'Scripting' started by gevarre, Sep 4, 2018.

  1. gevarre

    gevarre

    Joined:
    Jan 19, 2009
    Posts:
    132
    Hi,
    I'm trying to make a smoke system that changes color when things happen (ie: the smoke turns temporarily black when fuel is added to a fire). The following works:

    Code (CSharp):
    1. public ParticleSystem smoke;
    2. ParticleSystem.ColorOverLifetimeModule smokeColorModule;
    3. public Gradient gradient_smokeBlack;
    4.  
    5. void Start()
    6.     {
    7.         smokeColorModule = smoke.colorOverLifetime;
    8.     }
    9.  
    10. void Update()
    11. {
    12.     if (Input.GetButtonDown("Fire1"))
    13.     {
    14.         smokeColorModule.color = new ParticleSystem.MinMaxGradient(gradient_smokeBlack);
    15.     }
    16. }
    The only problem is, all the particles that already exist also change to the new color (ie: black). I only the particles generated after the change to have the new color. I don't want to have to create an entirely new particle system with the new color and try to sync it to the old one because that would get really complicated since there are other things that will happen.

    Any ideas how to do this? Thanks.
     
  2. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    The color module is applied during rendering, so applies to all particles.
    The only way I can think of, to affect only newly spawned particles, would be to change the Start Color in the main module. However you cannot assign a gradient-over-particle-lifetime to this setting.
     
    karl_jones likes this.
  3. gevarre

    gevarre

    Joined:
    Jan 19, 2009
    Posts:
    132
    Thanks. I just started to figure that out this morning, and now that I've had more time to think about it, it makes more sense, since all particles in the system are referencing one gradient and if you change it, then they all change.

    I finally got it working by using two systems and ParticleSystem.Play() and .Stop(). However, now I have a z-fighting issue, even if the second particle system is a child of the first. Since the particle system editor allows you to make subsystems, I would have assumed that sorting would apply to all the subsystems, but that appears not to be the case. I would consider this a bug, or at least a very much-needed ability: a button under Sort Mode in the Renderer module that says "apply sort mode to all subsystems". It's such a basic need for any kind of advanced setup.

    Anyway, messing with the Sorting Fudge setting "mostly" fixes it, though the particles still don't intermingle, but it's good enough for now, so thank you :)
     
  4. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    In principle I agree, but correct sorting of transparencies in real-time rendering is still a mostly unsolved problem, so we are stuck with these hacks for now.

    Glad you got it working!
     
  5. jRocket

    jRocket

    Joined:
    Jul 12, 2012
    Posts:
    700
    You could always use SetCustomParticleData and a custom shader to do it.