Making Sprites Flash in a 2D Game...

I was wanting to make my sprites flash in a 2D game when a character takes damage. A long time ago, I made an XNA game in which I created an alternate white sprite for the player’s sprite (programatically I think) then blended this with the original player sprite so as to make it look “whiter”.

I was asking about how to do this programatically in Unity, though someone suggested I might try setting the color attribute of a shader instead. The standard shader seems to assume a lighting system is present, and the other shaders I tried either don’t support tiling or don’t allow the color to be set. Is there an existing shader that will blend a white color into my sprites without lighting?

Someone also suggested just coding this in a new GLSL shader. I could go ahead and do this if it is preferable, though can it be layered on top of a 2D lighting system (separate shader) if I do add one later?

Why don’t u just change the Sprite Renderers color for a like half a second when hit then change it back to white?

So like u for example if you wanted to make it flash red then you could make a bool called “hit” and set “hit” to be true when hit then do somethin like -

if (hit == true) {
            GetComponent<SpriteRenderer> ().color = Color.red;
            StartCoroutine(whitecolor());
        }

Then u can like make a Coroutine like this -

IEnumerator whitecolor() {
        yield return new WaitForSeconds(0.5);
        GetComponent<SpriteRenderer> ().color = Color.white;
        hit = false;
    }

So your player would flash red then go back to normal and it wont make the entire sprite red itll just like make it like tinted red i think thats easier then making a GLSL shader to do it lol

1 Like

@datahead8888 or u could instantiate a white light that only affects your sprite over the player when hit but i think i like the other way i said above this

The sprite renderer already has a color of white by default, which causes the sprites to show up normally. I can only change it to other colors, which are really “darker” than white. This is the sort of thing that led a couple people to suggest writing a shader (Unity actually uses a language other than GLSL it turns out, though you can embed GLSL).

I just checked in BatMan on the NES, though, and the characters don’t appear to flash using a white sprite - it was either orange or yellow. I probably should try both of these colors a bit first, since they can easily be done using the sort of technique you outlined above.

You can use a shader, there’s a brilliant Unity Answer here with an example: Shader to flash a 2d sprite to white? - Questions & Answers - Unity Discussions

You create a new material with that shader and apply it to your sprites, either on the Editor or programmatically.

Here’s a simple co-routine to switch the flashAmount on the material:

public IEnumerator Flash()
    {
        while(isInvulnerable) {
  
            if(MathHelper.IsTimeEven())
            {
                GetComponent<Renderer>().material.SetFloat("_FlashAmount",0.8f);
            }
            else
            {
                GetComponent<Renderer>().material.SetFloat("_FlashAmount",0);
            }
      
            yield return null;
        }
    }

I may add a 2D lighting system later, which would certainly require a shader. If I decide to use a shader in order to allow sprites to be “whitified”, is it advisable to try to get the two different shaders to run in sequence? I understand it is possible by using multiple passes, though some people have recommended combining them for performance. This, however, is not at all modular, especially if I borrow code for the 2D lighting system. My game in only 2D, anyways.

in that case just swap the material when you want the sprite to flash, and swap it back after.

    Material originalMaterial;
    bool flashing;
    public Material flashMaterial;

    void Start () {
        if (GetComponent<SpriteRenderer>().material != null)
            originalMaterial = GetComponent<SpriteRenderer>().material;
    }

    public void FlashWrapper() {
        if (!flashing)
            StartCoroutine("Flash");
    }

    IEnumerator Flash() {
    
        flashing = true;
        GetComponent<SpriteRenderer>().material = flashMaterial;
        yield
        return new WaitForSeconds(1f);
        GetComponent<SpriteRenderer>().material = originalMaterial;
        yield
        return new WaitForSeconds(1f);
        flashing = false;
    }

You’d want to load the material from resources if adding classes dynamically.