Skip to content

How to animate effects

The custom material inspector properties can be animated through the Animation window as any other Unity component.

If you don’t know how this is done you can follow this video:

Please keep in mind that UI material properties can’t be animated using the Animator, the reason being that Unity won’t allow you to animate shared material properties. Unity UI Images materials are always shared, which means that all Images use the exact same material instance of a particular Image and therefore if a property is changed for one Image material all the other Images that share material will change too. Since Unity won’t allow this behavior it doesn’t support using the Animator in UI Material properties. And unfortunately I can’t do anything about it.

I recommend using an amazing free asset in the store called DOTween to animate the UI material properties through code. There are worked examples further down this page.

Alternatively you can also use this free asset called (Animate UI Materials):

https://assetstore.unity.com/packages/2d/gui/animate-ui-materials-253197?aid=1101l52IjU Also consider that since UI material instances are shared you may want to create a copy of each material through script on an Awake method:

void Awake()
{
Image uiImage = GetComponent<Image>();
uiImage.material = new Material(uiImage.material);
}

DOTween can tween a material property directly, which makes it the easiest route for UI and for anything you want to trigger from code. It is free on the Asset Store, and everything below needs using DG.Tweening;.

The Shine effect is the clearest example, since _ShineLocation moves the highlight band across the sprite from 0 on one edge to 1 on the other. Enable Shine in the Material Inspector first: tweening the property does nothing while the effect is off.

using UnityEngine;
using DG.Tweening;
public class ShineOnce : MonoBehaviour
{
private Material mat;
private void Awake()
{
mat = GetComponent<Renderer>().material;
}
public void Shine()
{
mat.SetFloat("_ShineLocation", 0f);
mat.DOFloat(1f, "_ShineLocation", 0.5f).SetLink(gameObject);
}
}

SetLink(gameObject) kills the tween if the object is destroyed. Without it a tween outliving its material throws.

For a shine that repeats with a gap between passes, a Sequence is what you want. Note LoopType.Restart rather than Yoyo: yoyo would send the band back the way it came, and the point here is that every pass runs in the same direction.

using UnityEngine;
using DG.Tweening;
public class ShineLoop : MonoBehaviour
{
[SerializeField] private float sweepDuration = 0.5f;
[SerializeField] private float pauseBetween = 2f;
private Sequence sequence;
private void Start()
{
Material mat = GetComponent<Renderer>().material;
sequence = DOTween.Sequence();
sequence.AppendCallback(() => mat.SetFloat("_ShineLocation", 0f));
sequence.Append(mat.DOFloat(1f, "_ShineLocation", sweepDuration));
sequence.AppendInterval(pauseBetween);
sequence.SetLoops(-1, LoopType.Restart);
sequence.SetLink(gameObject);
}
}

The callback resets the band to the starting edge at the top of every loop, so each pass starts from the same place no matter where the previous one ended.

That shape works for any property, not just shine. Swap in _FadeAmount for a repeating dissolve, or _HitEffectBlend with a short duration and no pause for a flash.

Same code, with the two UI rules from Scripting. Copy the material in Awake so the tween does not move every Image sharing it, and if the Image is masked, tween materialForRendering instead:

Material mat = image.materialForRendering;
mat.DOFloat(1f, "_ShineLocation", 0.5f).SetLink(gameObject);