UGUI自己的不规则图形精确点击策略
根据像素的透明度来判断
设置最小透明度:
GetComponent<Image>().alphaHitTestMinimumThreshold = 0.1f;
同时对应Texture需要在高级设置中开启 可读/可写功能,这样才能获取每个像素的信息
缺点:
图片内存增大,而且不能并入图集
可行的不规则图形精确点击策略
使用组件多边形2D碰撞器来检测点击点是否有效
using UnityEngine;
using UnityEngine.UI;
public class CustomImage : Image
{
//多边形2D碰撞器
private PolygonCollider2D _polygon;
private PolygonCollider2D Polygon
{
get
{
if (_polygon == null)
_polygon = GetComponent<PolygonCollider2D>();
return _polygon;
}
}
//检测screenPoint是否有效
public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)
{
Vector3 point;
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, screenPoint, eventCamera, out point);
return Polygon.OverlapPoint(point);
}
}
鼠标右键快捷生成CustomImage:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
public class CustomImageEditor : Editor
{
private const int UI_LAYER = 5;//Canvas的layer
[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;
}
}