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

Trying to use animated Emission for flashing effects.

Discussion in 'Shaders' started by TabuuForteAkugun, Jul 11, 2018.

  1. TabuuForteAkugun

    TabuuForteAkugun

    Joined:
    Sep 28, 2015
    Posts:
    58
    Hi everyone,

    I've attached snapshots depicting my problem.

    I am developing a Super Smash Brothers fangame, and am currently working on Mario. (I don't intend to release it for a very long time, no need to worry about Ultimate lol)

    So in my code, I have animation event to set the R, G and B components of my emission color in the Standard shader, I have a duration event as well that dictates how long it lasts, then one final event that applies the color.

    In Update(), I placed code to gradually restore the emission color back to 0 (black, none).

    However, Mario has the following problems

    1, only his face turns red-tinted emissive, in this case. My code is supposed to apply it to ALL his materials.
    2, the face doesn't lerp properly: slowly goes to fully red

    Code.

    fit_FlashColor.r/g/b.

    Code (CSharp):
    1. public override void SetFlashR(float red)
    2. {
    3.         fit_FlashColor.r = red;
    4. }
    Set Flash. Here I clearly have a for loop that's supposed to get all SkinnedMeshRenderers, which all use the same shader (standard shader) Again, only the face skinnedmeshes turn red.

    Code (CSharp):
    1. // Apply flash effect.
    2.     public override void Flash()
    3.     {
    4.         for (int f = 0; f < GetComponentsInChildren<SkinnedMeshRenderer>().Length; f++)
    5.         {
    6.             GetComponentsInChildren<SkinnedMeshRenderer>()[f].material.SetColor("_EmissionColor", fit_FlashColor);
    7.         }
    8.     }
    Code to Lerp back to normal. What happens here? The face is tinted red as intended, however it slowly and gradually fades into a solid red. Like the error shader, but bright red.

    Code (CSharp):
    1. void FixedUpdate()
    2.     {
    3.         [...]
    4.         // Apply flash and diminish it.
    5.         if (fit_FlashColor.r > 0f || fit_FlashColor.g > 0f || fit_FlashColor.b > 0f)
    6.         {
    7.             for (int fl = 0; fl < gameObject.GetComponentsInChildren<SkinnedMeshRenderer>().Length; fl++)
    8.             {
    9.                fit_FlashColor.r -= (0.01f * fit_FlashTime) * Time.deltaTime;
    10.                 fit_FlashColor.g -= (0.01f * fit_FlashTime) * Time.deltaTime;
    11.                 fit_FlashColor.b -= (0.01f * fit_FlashTime) * Time.deltaTime;
    12.                 gameObject.GetComponentsInChildren<SkinnedMeshRenderer>()[fl].material.SetColor("_EmissionColor",
    13.                     Color.Lerp(fit_FlashColor, Color.black, fit_FlashTime));
    14.             }
    15.         }
    16.     }
    Normal
    Screenshot (79).png

    Red tinted.
    Screenshot (80).png

    Full, solid red after Lerp finishes.
    Screenshot (81).png
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Because you're only applying it to one material. Presumably the model has multiple materials, not just one. You can iterate over the renderer.materials array instead of just the singular .material variable, or you can use a MaterialPropertyBlock.

    MaterialPropertyBlock matBlock = new MaterialPropertyBlock();
    matBlock.SetColor("_Emission", FlashColor);
    skinnedMeshRenderer.SetPropertyBlock(matBlock);


    I'm not exactly sure what you intend, so I can't tell you exactly what you want, or really understand exactly what you expect your code to do. You're also iterating over the color for each skinned mesh renderer, which you likely do not want to do as the speed at which the color changes will depend on how many skinned mesh renderers there are.

    However if your expectation is for the emissive color to flash at some rate, as well as slowely fade to black, you probably want to not subtract from the color value at a fixed rate from all components, but instead use a lerp between the initial flash color and black over the time, then use another lerp to fade between that color and black using some periodic function (like a sine wave or modulo) driven by the actual game time.
     
    Hanstumiklo likes this.