UI 4.6 Flash effect/Saturation for Image?

Hello all. I’m trying to make a flash effect on an icon in our UI. By flash effect, I mean to saturate the image from its normal colors to pure white and back again. My intention is to drive the animation from C# script via tween/easing. The icon I’m working with is in a prefab, and numerous copies of the prefab are instantiated in a layout group to display player inventory. When you get more of a thing I’d like that item in the list to flash to white to draw your eye to the fact that you now have more of them.

The prefab is a root game object with only 2 children, one child is text (to display how many) the other is the icon to show. The icon is displayed via the new 4.6 Image component (we’re changing the actual asset to display from script with no problems).

I feel like this should be easy to accomplish but apparently it is very difficult. The closest I’ve come thus far is by adding a material to the Image that has a shader attached that allows me to set the _FlashEffect amount (from 0 → 1). It sort of works in that my image does flash, however ALL of my images in the inventory flash which is not desired. I got the shader from here:

From my sleuthing online this seems to be because I’m not getting the material.shader from the renderer which would cause an instance of the material to be made. Instead the only way i’ve been able to get at the shader of an image is like so:

            Image resIcon = flashTarget.GetComponentInChildren<Image>();
            if (resIcon != null)
                resIcon.material.SetFloat("_FlashAmount", flashValue);

After a full day searching and reading tons of stuff I’m turning here for help. Is there a way to get at the renderer of an image component that I’ve missed (does it even have one?), or is there another way to accomplish my goal? Any insight into solving this issue would be very much appreciated. Thanks for your time.

EDIT: adding my own answer as a work around below. while it is getting the job done it is less than ideal and any pointers to a better way would be appreciated.

So I have a functional workaround for this which I’m less than happy with, but it does work. For all of my buttons that need to have a flashing effect on the icon I actually give them 2 Image components (attached as separate children of the main button). One of these icons has the flash/saturation shader I listed earlier as a material set on that icon:

On start I set the flash icon to alpha 0 via a canvas group and then SetActive(false). Later on when I need that button to do it’s flash effect I SetActive(true) on the secondary icon, then use an iTween.ValueTo with a call back to tween the alpha from 0 → 1 → 0 over the time the tween executes.

As I said this does work, but it means every button now has 2 icons, both have to be loaded when data changes etc. There must be a better way.

I am some years late, but here is how to make it work:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class ImageFlasher : MonoBehaviour {
    private Image image; 
    [Range(0, 1)]
    public float flash = 0;

    void Start() {
        image = gameObject.GetComponent<Image>();
        image.material = new Material(image.material);
    }
     
    void Update() {
        image.material.SetFloat("_FlashAmount", flash);
    }

}

This is what solves the whole ‘all images are flashing all at once’

image.material = new Material(image.material);

Although, I assume that this makes so that the images stop batching, but who cares?

Maybe, you can use blink effect like this :

void Update()
{
		if (resIcon)
		{
			Color temp = resIcon.GetComponent<Image>().color;
			resIcon.GetComponent<Image>().color = new Color(temp.r,temp.g,temp.b,Mathf.Abs(Mathf.Sin(Time.time * 2f)));
		}
}

You can do this with an animation. Highlight the button you’re going to use as a prefab an open the Animation Window.

Add a curve and select Buttons.Colors.Highlighted then do the same and select Buttons.Colors.Normal.

Start the animation for both with the default color then set a new frame that’ll be the middle one say half a second in and change the color for both Highlighted and Normal then set a new frame at one second an go back to the default color.

As a test I just created a script to flash when clicked and stop when clicked again:

using UnityEngine;
using System.Collections;

public class FlashButton : MonoBehaviour {
	
	private bool playAnim = false;
	private Animator anim;

	void Start()
	{
		anim = GetComponent<Animator>();
	}

	public void switchFlash()
	{
		playAnim = !playAnim;

		anim.SetBool("flash", playAnim);
	}
}

I made sure the button had an Animator element:

And set the Animator to have two states and a bool, I called the bool flash:

41077-buttonflashanim.png

Start the game and clicked the button and it starts flashing, click again and it stops. Not exactly what you want but just animate the flash and take into account sometimes the button will be highlighted and sometimes it will be normal, cover both and you should be OK.

All you need to do is reference the script on the button to tell it when to flash, with my example that’s with a click but if you have a reference for the button you can call the function when that buttons items increase.

Another late answer, but it’s one I don’t see so I’ll post it in case someone’s looking for alternative solutions to the ones above. This one worked particularly well for me since I wanted to Lerp to the white color.

Only drawback is that this method ignores alpha transparency of the original sprite.

  1. Make a child object under the sprite you want to turn white.
  2. Give it an Image component with default UI sprite.
  3. Add Mask component to the parent object.

The original sprite will now be completely white, and you can Lerp the child image’s color if you want a smooth transition between normal color and pure white.

Hope this helps someone :slight_smile: