Search Unity

How to make a flashing white sprite?

Discussion in '2D' started by NotMyUsernameAgain, May 23, 2018.

  1. NotMyUsernameAgain

    NotMyUsernameAgain

    Joined:
    Sep 28, 2017
    Posts:
    139
    Hi everyone,
    very simple question.

    I want to make my sprite flash in white.

    So how am I able to make my sprite white and then access the color via code or animation?
     
  2. Perkki

    Perkki

    Joined:
    Sep 30, 2017
    Posts:
    15
    One easy possibility is to place white version of your sprite on top of it. You can control it's transparency by setting alpha value for sprite renderer's color from code or animation to make flashing effect.

    Better way is to use customised sprite shader.
     
  3. TheDryden

    TheDryden

    Joined:
    Oct 20, 2017
    Posts:
    6
    The post does not solve the original request. I when I wrote this I forgot that I was changing the alpha, not the color, of the sprite. I'm leaving this here for context.

    I use the following code to strobe my sprites any color I want (I usually use white as well though). In order for this to work you'll either need to add a bool name strobing to your class, or remove those part of the code (its just there to stop two or more call to strobe from conflicting with one another).

    Basically you call the public function, which first stops if its already strobing, then stores the original color, then calls a helper function. The helper then switches between the two colors, pausing for .3 seconds between.

    With this method you don't need to create a new sprite, just change the color (or alpha) of the existing one.

    Code (CSharp):
    1. public void StrobeColor( int _strobeCount, Color _toStrobe )
    2.     {
    3.         if (strobing)
    4.             return;
    5.  
    6.         strobing = true;
    7.  
    8.         SpriteRenderer mySprite = this.GetComponent<SpriteRenderer>();
    9.         Color oldColor = mySprite.color;
    10.  
    11.         StartCoroutine(StrobeColorHelper(0, (( _strobeCount * 2) - 1), mySprite, oldColor, _toStrobe));
    12.  
    13.     }
    14.  
    15.     public void StrobeAlpha( int _strobeCount, float a)
    16.     {
    17.         SpriteRenderer mySprite = this.GetComponent<SpriteRenderer>();
    18.         Color toStrobe = new Color(mySprite.color.r, mySprite.color.b, mySprite.color.g, a);
    19.         StrobeColor(_strobeCount, toStrobe);
    20.     }
    21.  
    22.     private IEnumerator StrobeColorHelper( int _i, int _stopAt, SpriteRenderer _mySprite, Color _color, Color _toStrobe)
    23.     {
    24.         if(_i <= _stopAt)
    25.         {
    26.             if (_i % 2 == 0)
    27.                 _mySprite.color = _toStrobe;
    28.             else
    29.                 _mySprite.color = _color;
    30.  
    31.             yield return new WaitForSeconds(.3f);
    32.             StartCoroutine(StrobeColorHelper( (_i+1), _stopAt, _mySprite, _color, _toStrobe));
    33.         }
    34.         else
    35.         {
    36.             strobing = false;
    37.         }
    38.     }
     
    Last edited: May 25, 2018
  4. NotMyUsernameAgain

    NotMyUsernameAgain

    Joined:
    Sep 28, 2017
    Posts:
    139
    If I create a "New Material" and make the "Rendering Mode" to "Cutout" and the "emission color" white and drag&drop it on my sprite, I'm able to make my sprite.
    However it becomes a shader (instead of a material) and I don't know how to access the shader via code.

    @TheDryden
    I'm sorry, but could you explain the code a bit please?
     
  5. TheDryden

    TheDryden

    Joined:
    Oct 20, 2017
    Posts:
    6
    Yeah sorry when I posted this I forgot the only color you can't change the sprite to is white, what I'm actually doing with that code is changing the alpha.

    With that said the theory is that you can change the color of any sprite, and it unity will blend the colors in the sprite to try and match the color you chose. This is particularly useful with UI elements as you can have a white element and use the color feature to change it to match the context of the menu.

    Unfortunately the default color of sprites is white, which mean you can't actually use this feature to change the color of a sprite too white. I wrote this code a while ago, and simple forgot that my implementation was to actually change the alpha (to .5 or 50%) instead of changing it to white.

    Sorry for the confusion. If you'd like more details on what the code does, ask and I'll do my best to answer, but for now I'm going to edit my answer to reflect that it doesn't solve the original question.
     
  6. NotMyUsernameAgain

    NotMyUsernameAgain

    Joined:
    Sep 28, 2017
    Posts:
    139
    @TheDryden
    OK, no problem

    So in the end is there no other way around but to make another sprite in white?

    I mean I can get a white sprite if I play with the shader,
    I just do not know how to access the shader's properties via code.
     
  7. Perkki

    Perkki

    Joined:
    Sep 30, 2017
    Posts:
    15
    Haven't done this by myself, but look from unity's documentation for Material SetFloat, SetInt etc...
     
  8. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Here's an example of a modified default Sprite shader with an exposed "_Color" field for color changing.
    Code (CSharp):
    1.  
    2. Shader "Custom/Sprites/Colorized"
    3. {
    4.     Properties
    5.     {
    6.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    7.         _Color ("Color", Color) = (1,1,1,0)
    8.         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    9.     }
    10.  
    11.     SubShader
    12.     {
    13.         Tags
    14.         {
    15.             "Queue"="Transparent"
    16.             "IgnoreProjector"="True"
    17.             "RenderType"="Transparent"
    18.             "PreviewType"="Plane"
    19.             "CanUseSpriteAtlas"="True"
    20.         }
    21.  
    22.         Cull Off
    23.         Lighting Off
    24.         ZWrite Off
    25.         Blend One OneMinusSrcAlpha
    26.  
    27.         Pass
    28.         {
    29.         CGPROGRAM
    30.             #pragma vertex vert
    31.             #pragma fragment frag
    32.             #pragma multi_compile _ PIXELSNAP_ON
    33.             #include "UnityCG.cginc"
    34.          
    35.             struct appdata_t
    36.             {
    37.                 float4 vertex   : POSITION;
    38.                 float4 color    : COLOR;
    39.                 float2 texcoord : TEXCOORD0;
    40.             };
    41.  
    42.             struct v2f
    43.             {
    44.                 float4 vertex   : SV_POSITION;
    45.                 fixed4 color    : COLOR;
    46.                 float2 texcoord  : TEXCOORD0;
    47.             };
    48.          
    49.             fixed4 _Color;
    50.  
    51.             v2f vert(appdata_t IN)
    52.             {
    53.                 v2f OUT;
    54.                 OUT.vertex = UnityObjectToClipPos(IN.vertex);
    55.                 OUT.texcoord = IN.texcoord;
    56.                 #ifdef PIXELSNAP_ON
    57.                 OUT.vertex = UnityPixelSnap (OUT.vertex);
    58.                 #endif
    59.  
    60.                 OUT.color = IN.color;
    61.                 return OUT;
    62.             }
    63.  
    64.             sampler2D _MainTex;
    65.             sampler2D _AlphaTex;
    66.             float _AlphaSplitEnabled;
    67.  
    68.             fixed4 SampleSpriteTexture (float2 uv)
    69.             {
    70.                 fixed4 color = tex2D (_MainTex, uv);
    71.  
    72. #if UNITY_TEXTURE_ALPHASPLIT_ALLOWED
    73.                 if (_AlphaSplitEnabled)
    74.                     color.a = tex2D (_AlphaTex, uv).r;
    75. #endif
    76.  
    77.                 return color;
    78.             }
    79.  
    80.             fixed4 frag(v2f IN) : SV_Target
    81.             {
    82.                 fixed4 textureColor = SampleSpriteTexture (IN.texcoord) * IN.color;
    83.                 fixed4 c = lerp(textureColor, _Color, _Color.a);
    84.                 c.rgb *= textureColor.a;
    85.                 c.a = textureColor.a;
    86.                 return c;
    87.             }
    88.         ENDCG
    89.         }
    90.     }
    91. }

    Here's how you can control an object with this material using C#:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [RequireComponent(typeof(SpriteRenderer))]
    4. public class Example : MonoBehaviour
    5. {
    6.     private const string SHADER_COLOR_NAME = "_Color";
    7.     private Material material;
    8.  
    9.     void Awake()
    10.     {
    11.         // makes a new instance of the material for runtime changes
    12.         material = GetComponent<SpriteRenderer>().material;
    13.     }
    14.  
    15.     private void Update()
    16.     {
    17.         if (Input.anyKey)
    18.         {
    19.             if (Input.GetKeyDown(KeyCode.Space))
    20.             {
    21.                 SetColor(Color.white);
    22.             }
    23.  
    24.             if (Input.GetKeyDown(KeyCode.Backspace))
    25.             {
    26.                 SetColor(new Color(1,1,1,0));
    27.             }
    28.         }
    29.     }
    30.  
    31.     private void SetColor(Color color)
    32.     {
    33.         material.SetColor(SHADER_COLOR_NAME, color);
    34.     }
    35. }
    You should be able to use this to expand into fading alphas, looping for flashing, etc.
     
  9. BarthaSzabolcs

    BarthaSzabolcs

    Joined:
    Apr 9, 2019
    Posts:
    8
    In my opinion, the easiest way is to create a new material set to GUI/TextShader, and swap the SpriteRenderers material with it, then swap it back.

    I made a quick tutorial about this, you can find the source code in the description:
     
    Mixla, AnjelCorp, Threepwood and 4 others like this.
  10. rtncnk

    rtncnk

    Joined:
    Aug 10, 2020
    Posts:
    5
    Hey man,
    This looks really neat..I was trying to achieve the same effect with the animator but this makes much more sense...Cheers..=)
     
  11. BarthaSzabolcs

    BarthaSzabolcs

    Joined:
    Apr 9, 2019
    Posts:
    8
    Am glad it helped rtncnk. :)
     
  12. wfj2494

    wfj2494

    Joined:
    Jun 21, 2021
    Posts:
    1
    Hey this is a post from months ago, but you can do it in the animator by adding the Sprite Renderer's Material Reference as a property to animate in the Animation window, then changing it for one keyframe or whatever in Record mode.
     
  13. daogework

    daogework

    Joined:
    Jul 17, 2020
    Posts:
    3
  14. PandaTheBagel

    PandaTheBagel

    Joined:
    Nov 19, 2022
    Posts:
    2
    Is it possible to do this kind of effect with vector graphics?
     
  15. bwaite87

    bwaite87

    Joined:
    Nov 23, 2017
    Posts:
    18
    The above answers work great.
    If you want to be able to do it smoothly (or with HDR for glow) I've put together a brief video to explain how this is done using URP and Shadergraph.

     
    andreiagmu, Boyozu and Pharan like this.