2
\$\begingroup\$

The goal is to remove the particles via script with fade effect. But I'm not just interested in an alternative, I want to understand why my code doesn't work.

The code below is modified to show only the important parts. I can't know before what time the particles will be dissolved, so I can't set the parameter from the editor.

StarsConfig.Stars.colorOverLifetime.color.gradient.SetKeys This is the important point (see the log image). The gradient does not take my new values but alphaKey is correct.

Why ? Thanks

private bool FadeStarts = false;

void Update()
{
    if (FadeStarts) return;
    StartCoroutine(fadeStars(false));
}


private IEnumerator fadeStars(bool show)
{

    FadeStarts = true;

    ParticleSystem.ColorOverLifetimeModule c = new ParticleSystem.ColorOverLifetimeModule();

    c = StarsConfig.Stars.colorOverLifetime;

    Gradient g = c.color.gradient;

    Debug.Log("OFF " + c.color.gradient.alphaKeys[0].alpha + " --> " + g.alphaKeys[0].alpha);

    GradientAlphaKey[] alphaKey = new GradientAlphaKey[2];
    alphaKey[0] = c.color.gradient.alphaKeys[0];
    alphaKey[1] = c.color.gradient.alphaKeys[1];


    while (c.color.gradient.alphaKeys[0].alpha > 0f) {

        alphaKey[0].alpha -= StarsConfig.VelocityAlpha * Time.deltaTime;
        alphaKey[1].alpha -= StarsConfig.VelocityAlpha * Time.deltaTime;

        StarsConfig.Stars.colorOverLifetime.color.gradient.SetKeys(c.color.gradient.colorKeys, alphaKey);

        Debug.Log("g " + alphaKey[0].alpha + " --> " + StarsConfig.Stars.colorOverLifetime.color.gradient.alphaKeys[0].alpha);

        /*
        StarsConfig.Stars.colorOverLifetime.color.gradient.SetKeys(
            new GradientColorKey[] { new GradientColorKey(Color.white, 0f),
                                    new GradientColorKey(Color.white, 1.0f) },
            new GradientAlphaKey[] { new GradientAlphaKey(StarsConfig.Stars.colorOverLifetime.color.gradient.alphaKeys[0].alpha - (StarsConfig.VelocityAlpha * Time.deltaTime), 0f),
                                    new GradientAlphaKey(StarsConfig.Stars.colorOverLifetime.color.gradient.alphaKeys[1].alpha - (StarsConfig.VelocityAlpha * Time.deltaTime), 1f) });

        */

        yield return 0;
    }

    StarsConfig.Stars.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);


    FadeStarts = false;
}

enter image description here

UPDATE

Ed_Marty's suggestion is correct, and the solution is there (thanks!). But I would like to understand what is the difference between these two codes.

This code works

var col = StarsConfig.Stars.colorOverLifetime;
while (col.color.gradient.alphaKeys[0].alpha > 0f) {

    float alpha = StarsConfig.Stars.colorOverLifetime.color.gradient.alphaKeys[0].alpha - (StarsConfig.VelocityAlpha * Time.deltaTime);

    Gradient grad = new Gradient();
    grad.SetKeys(
        new GradientColorKey[] {
            new GradientColorKey(Color.white, 0.0f),
            new GradientColorKey(Color.white, 1.0f) }, 
        new GradientAlphaKey[] {
            new GradientAlphaKey(alpha, 0.0f),
            new GradientAlphaKey(alpha, 1.0f) });

    col.color = grad;

    yield return 0;
}

And this doesn't work

while (StarsConfig.Stars.colorOverLifetime.color.gradient.alphaKeys[0].alpha > 0f) {

    float alpha = StarsConfig.Stars.colorOverLifetime.color.gradient.alphaKeys[0].alpha - (StarsConfig.VelocityAlpha * Time.deltaTime);

    StarsConfig.Stars.colorOverLifetime.color.gradient.SetKeys(
        new GradientColorKey[] { new GradientColorKey(Color.white, 0f),
                                 new GradientColorKey(Color.white, 1.0f) },
        new GradientAlphaKey[] { new GradientAlphaKey(alpha, 0f),
                                 new GradientAlphaKey(alpha, 1f) });

    yield return 0;
}
\$\endgroup\$
4
  • \$\begingroup\$ Have you tried doing it how the docs recommend? docs.unity3d.com/ScriptReference/… \$\endgroup\$
    – Ed Marty
    Commented May 26, 2019 at 14:55
  • \$\begingroup\$ Yes, if you check my code I created a Gradient g but I don't use it, because it has remained from the previous tests. \$\endgroup\$
    – Baro
    Commented May 26, 2019 at 14:59
  • 1
    \$\begingroup\$ I mean specifically how they fetch the component and assign the gradient and color separately. You’re doing it all in one line. \$\endgroup\$
    – Ed Marty
    Commented May 26, 2019 at 15:21
  • \$\begingroup\$ @EdMarty Thank you very much, you helped me to solve, if now someone explains to me the difference between the two codes I would be grateful :) \$\endgroup\$
    – Baro
    Commented May 26, 2019 at 16:25

1 Answer 1

3
\$\begingroup\$

ColorOverLifetimeModule.color is a property getter that returns a copy of the MinMaxGradient struct's values.

So your first earlier code StarsConfig.Stars.colorOverLifetime.color.gradient.SetKeys(...) takes this copy, and modified the copy... then discards it. Since you were modifying the copy, your particle system's original values remain unchanged.

The magic line in the new code is col.color = grad, which takes the modified gradient you've made and hands it back to the module to update its internal state.

\$\endgroup\$
6
  • \$\begingroup\$ How does it hand back? ColorOverLifetimeModule is a struct as well, so we copy it to the col and that's ok, but we never put it back to the StarsConfig.Stars.colorOverLifetime and it still works. Why? \$\endgroup\$
    – Serg
    Commented Nov 22, 2020 at 19:20
  • \$\begingroup\$ There's nothing that would prevent ColorOverLifetimeModule from storing a reference to its source particle system, to communicate back to it after you modify its properties. \$\endgroup\$
    – DMGregory
    Commented Nov 22, 2020 at 19:26
  • \$\begingroup\$ Ok, thanks! I see it now in source code, the struct definition from meta is not full. Still quite an unusual pattern for me in C#. \$\endgroup\$
    – Serg
    Commented Nov 22, 2020 at 19:34
  • \$\begingroup\$ Why might this code not work? ................ ColorOverLifetimeModule colorOverLifetime = _particle.colorOverLifetime; MinMaxGradient color = colorOverLifetime.color; color.gradient.colorKeys[1] = new GradientColorKey(new Color(1, 0, 0), 0.5f); colorOverLifetime.color = color; \$\endgroup\$
    – Serg
    Commented Nov 22, 2020 at 20:04
  • \$\begingroup\$ Sounds like you have a new Question you can post by clicking the "Ask Question" button. \$\endgroup\$
    – DMGregory
    Commented Nov 22, 2020 at 20:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .