Sprite Flash in Unity

Share on facebook
Facebook
Share on google
Google+
Share on twitter
Twitter
Share on linkedin
LinkedIn

Flashing effect is commonly used in Shoot ‘Em Up and Beat ‘Em Up games. It gives clue to players that those enemies or objects can be damaged and destroyed. I used this technique in the development of Burst Fighter. (The spaceships image above is from Burst Fighter)

The implementation in Unity is actually quite simple. We just need to change the default sprite shader with our custom flash shader that we will be creating right now. I won’t explain the basic of shader programming. You can find it on the internet easily. I personally recommend reading this article by Alan Zucconi before diving into shader programming.

The shader will look like this:


Shader "Sprites/Sprite Flash"
{
	Properties
	{
		[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
		_Color ("Tint", Color) = (1,1,1,1)
		[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
		_FlashColor ("Flash Color", Color) = (1,1,1,1)
		_FlashAmount ("Flash Amount", Range (0,1)) = 0
	}

	SubShader
	{
		Tags
		{ 
			"Queue"="Transparent" 
			"IgnoreProjector"="True" 
			"RenderType"="Transparent" 
			"PreviewType"="Plane"
			"CanUseSpriteAtlas"="True"
		}

		Cull Off
		Lighting Off
		ZWrite Off
		Blend One OneMinusSrcAlpha

		Pass
		{
		CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile _ PIXELSNAP_ON
			#include "UnityCG.cginc"
			
			struct appdata_t
			{
				float4 vertex   : POSITION;
				float4 color    : COLOR;
				float2 texcoord : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex   : SV_POSITION;
				fixed4 color    : COLOR;
				float2 texcoord  : TEXCOORD0;
			};
			
			fixed4 _Color;
			fixed4 _FlashColor;

			v2f vert(appdata_t IN)
			{
				v2f OUT;
				OUT.vertex = UnityObjectToClipPos(IN.vertex);
				OUT.texcoord = IN.texcoord;
				OUT.color = IN.color * _Color;
				#ifdef PIXELSNAP_ON
				OUT.vertex = UnityPixelSnap (OUT.vertex);
				#endif

				return OUT;
			}

			sampler2D _MainTex;
			sampler2D _AlphaTex;
			float _AlphaSplitEnabled;
			float _FlashAmount;


			fixed4 SampleSpriteTexture (float2 uv)
			{
				fixed4 color = tex2D (_MainTex, uv);

#if UNITY_TEXTURE_ALPHASPLIT_ALLOWED
				if (_AlphaSplitEnabled)
					color.a = tex2D (_AlphaTex, uv).r;
#endif //UNITY_TEXTURE_ALPHASPLIT_ALLOWED

				return color;
			}

			fixed4 frag(v2f IN) : SV_Target
			{
				fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;
				c.rgb = lerp(c.rgb, _FlashColor.rgb, _FlashAmount);
				c.rgb *= c.a;
				return c;
			}
		ENDCG
		}
	}
}

Look closer to this line.


c.rgb = lerp(c.rgb, _FlashColor.rgb, _FlashAmount);

The idea is we want to lerp our existing sprite color to _FlashColor based on _FlashAmount. Now, create a new material with this shader and attach it to your sprite. Next step is creating a C# script to interact with _FlashAmount value.


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpriteFlash : MonoBehaviour {

	public float flashSpeed;

	Material mat;

	bool isFlashing = false;

	private void Awake() {
		mat = GetComponent().material;
	}

	private void Update() {
		if(Input.GetKeyDown(KeyCode.Space))
			Flash();
	}

	private void Flash(){
		StartCoroutine(DoFlash());
	}

	IEnumerator DoFlash(){
		isFlashing = false;
		yield return new WaitForEndOfFrame();
		isFlashing = true;
		float flash = 1f;
		while (isFlashing && flash >=0)
		{
			flash -= Time.deltaTime * flashSpeed;
			mat.SetFloat("_FlashAmount", flash);
			yield return null;
		}
		isFlashing = false;
	}
}

That’s it! Now start play mode and press Space bar to flash the sprite. You can download the Unity project here: Unity Sprite Flash

this article is contributed by: claygamestudio.com

More to explorer

Week After Itch.io

Hello guys.  It’s been a week since our first demo release at Itch.io. At that time we thought that should be a

Dynamic 2D Water in Unity

In this tutorial we are going to simulate dynamic 2D water in Unity with simple physics calculation. This post is actually inspired

Leave a Comment

Your email address will not be published. Required fields are marked *