As The last ship sailed towards the distant horizon I sat there watching on a rock My mind slowly drifting away Forming into my... Dreamtale
Unity utils ExtendImage
2017-12-04 / 3 min read

Solution for Unity3d new UI: How to set button's interactable zone bigger than the attached image?

Use this ExtendImage instead of uGUI Image on your button, adjust the extend of ExtendImage to the proper value size.

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

namespace UnityEngine.UI
{
	/// <summary>
	/// 修改图片显示大小,触摸区域不变
<!-- more -->

	/// </summary>
	[ExecuteInEditMode ,AddComponentMenu("UI/Extend Image")]
	public class ExtendImage : Image
	{

		[Header ("Horizontal, Vertical")]
		[SerializeField]
		private Vector2 m_Extend=Vector2.zero;

		public Vector2 extend{
			get{ return m_Extend; }
			set{
				if(!m_Extend.Equals(value)){
					m_Extend = value;
					SetVerticesDirty();
				}
			}
		}

		protected override void OnPopulateMesh (VertexHelper toFill)
		{
			base.OnPopulateMesh (toFill);

			var rect = GetPixelAdjustedRect ();
			if (rect.width < m_Extend.x || rect.height < m_Extend.y) {
				return;
			}

			var ratioX = (rect.width - m_Extend.x) / rect.width;
			var ratioY = (rect.height - m_Extend.y) / rect.height;

			var verticesCount = toFill.currentVertCount;
			for (int i = 0; i < verticesCount; i++) {
				var v = new UIVertex ();
				toFill.PopulateUIVertex (ref v, i);
				v.position.x *= ratioX;
				v.position.y *= ratioY;
				toFill.SetUIVertex (v, i);
			}
		}

		public override void SetNativeSize()
		{
			if (overrideSprite != null)
			{
				float w = overrideSprite.rect.width / pixelsPerUnit;
				float h = overrideSprite.rect.height / pixelsPerUnit;
				rectTransform.anchorMax = rectTransform.anchorMin;
				rectTransform.sizeDelta = new Vector2(w+m_Extend.x, h+m_Extend.y);
				SetAllDirty();
			}
		}
	}
}

Please remember to put the Editor class of ExtendImage in Editor folder:

using UnityEngine;
using UnityEditor;

namespace UnityEditor.UI{
	[CustomEditor(typeof(UnityEngine.UI.ExtendImage), true)]
	public class ExtendImageEditor : ImageEditor {

		public override void OnInspectorGUI ()
		{
			base.OnInspectorGUI ();

			serializedObject.Update();
			EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Extend"), true);
			serializedObject.ApplyModifiedProperties();
		}
		
		[MenuItem("GameObject/UI/Extend Image")]
		public static void CreateExtendImage()
		{
			var selection = Selection.activeGameObject;
			if (!selection)
			{
				var canvas = FindObjectOfType<Canvas>();
				if (canvas == null)
				{
					canvas = new GameObject("Canvas").AddComponent<Canvas>();
					canvas.gameObject.AddComponent<CanvasScaler>();
					canvas.gameObject.AddComponent<GraphicRaycaster>();
				}
				selection = canvas.gameObject;
			}
			
			var img = new GameObject("ExtendImage").AddComponent<ExtendImage>();
			img.transform.SetParent(selection.transform);
		}
	}
	}
}