实现原理:重写Image组件,然后添加polygon2D组件调整可点击的区域
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CustomImage : Image
{
private PolygonCollider2D _polygon;
private PolygonCollider2D Polygon
{
get
{
if (_polygon == null)
_polygon = GetComponent<PolygonCollider2D>();
return _polygon;
}
}
/// <summary>
/// 事件响应区域的判断
/// </summary>
/// <param name="screenPoint"></param>
/// <param name="eventCamera"></param>
/// <returns></returns>
public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)
{
Vector3 point;
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, screenPoint, eventCamera, out point);
//只接收Polygon区域范围内的点击
return Polygon.OverlapPoint(point);
}
}
可通过编辑器扩展,在菜单栏中添加一个快捷功能
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
public class CustomImageEditor : Editor
{
private const int UI_LAYER = 5;
[MenuItem("GameObject/UI/CustomImage", priority = 0)]
private static void AddImage()
{
Transform canvasTrans = GetCanvasTrans();
Transform image = AddCustomImage();
if (Selection.activeGameObject!= null && Selection.activeGameObject.layer == UI_LAYER)
{
image.SetParent(Selection.activeGameObject.transform);
}
else
{
image.SetParent(canvasTrans);
}
image.localPosition = Vector3.zero;
}
private static Transform GetCanvasTrans()
{
Canvas canvas = GameObject.FindObjectOfType<Canvas>();
if (canvas == null)
{
GameObject canvasObj = new GameObject("Canvas");
SetLayer(canvasObj);
canvasObj.AddComponent<RectTransform>();
canvasObj.AddComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
canvasObj.AddComponent<CanvasScaler>();
canvasObj.AddComponent<GraphicRaycaster>();
return canvasObj.transform;
}
else
{
return canvas.transform;
}
}
private static Transform AddCustomImage()
{
GameObject image = new GameObject("Image");
SetLayer(image);
image.AddComponent<RectTransform>();
image.AddComponent<PolygonCollider2D>();
image.AddComponent<CustomImage>();
return image.transform;
}
private static void SetLayer(GameObject ui)
{
ui.layer = UI_LAYER;
}
}