UGUI; Multi image button transition

Hi all,

I have a few buttons in my UI which are actually made up from several different images - eg a sliced left/middle/right to support different widths. I’m wondering if there is an easy way to use the UI->Button component and have it transition (eg color tint) all the parts of my button; currently you can only set a single target image.

The ideal thing here would be if target image was actually a list/array so I can specify more than one image, and have the transition be applied to everything in that collection. I’ve inspected some of the classes involved but it seems that the bit where it actually alters the image is a bit deeper than I’m able to dig!

I was hoping I could possibly extend the UI.Button class to add a ‘TargetImages’ field, but I’ll need to override where the image modification is taking place, and that’s the bit I haven’t quite figured out.

Any help appreciated!

Apologies, I’ve answered my own question while it was being moderated. I’ve made a version of UI.Button which does what I need, with minimal effort. You set the targetGraphic to one of the ones you want to transition and it also affects it’s siblings. Can definitely be improved, but works for now. Code here in case it’s useful to anyone else. Note that I’ve disabled animation and sprite swap.

public class MultiImageButton : UnityEngine.UI.Button
{
	private Graphic[] m_graphics;
	protected Graphic[] Graphics
	{
		get
		{
			if(m_graphics == null)
			{
				m_graphics = targetGraphic.transform.parent.GetComponentsInChildren<Graphic>();
			}
			return m_graphics;
		}
	}

	protected override void DoStateTransition (SelectionState state, bool instant)
	{
		Color color;
		switch (state)
		{
		case Selectable.SelectionState.Normal:
			color = this.colors.normalColor;
			break;
		case Selectable.SelectionState.Highlighted:
			color = this.colors.highlightedColor;
			break;
		case Selectable.SelectionState.Pressed:
			color = this.colors.pressedColor;
			break;
		case Selectable.SelectionState.Disabled:
			color = this.colors.disabledColor;
			break;
		default:
			color = Color.black;
			break;
		}
		if (base.gameObject.activeInHierarchy)
		{
			switch (this.transition)
			{
			case Selectable.Transition.ColorTint:
				ColorTween (color * this.colors.colorMultiplier, instant);
				break;
			default:
				throw new NotSupportedException();
			}
		}
	}

	private void ColorTween(Color targetColor, bool instant)
	{
		if (this.targetGraphic == null)
		{
			return;
		}

		foreach(Graphic g in this.Graphics)
		{
			g.CrossFadeColor (targetColor, (!instant) ? this.colors.fadeDuration : 0f, true, true);
		}
	}
}

I found using the ‘Animation’ transition rather than adding scripting to be more convenient. The ‘Auto Generate Animation’ button that appears when you select ‘Animation’ as the transition type was handy for doing most of the set up; a couple of additional clicks to set the appropriate colour for the generated ‘Normal’ and ‘Pressed’ clips was all that was required after that.