有時候產品需求按鈕不能是長方形,要三角形,五邊形,甚至五角星行,這時你是不是方了,怎麼做???
別雞凍,其實unity有現成的哦!!!PolygonCollider2D!!!
給你的UI加上這個組件PolygonCollider2D,你就可以自定義形狀了!
當然形狀也可以代碼控制,就是設置不規則圖形的頂點位置,代碼如下:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class CustonCollider2D : MonoBehaviour, IPointerClickHandler
{
/// <summary>
/// 多邊形碰撞器
/// </summary>
private PolygonCollider2D polygonCollider;
private RectTransform rectTransform;
void Start()
{
//獲取多邊形碰撞器
polygonCollider = transform.GetComponent<PolygonCollider2D>();
//獲取RectTransform
rectTransform = transform.GetComponent<RectTransform>();
Vector2[] v = new Vector2[6];
v[0] = new Vector2(-40, -15);
v[1] = new Vector2(-20, 40);
v[2] = new Vector2(25, 30);
v[3] = new Vector2(40, 0);
v[4] = new Vector2(40, -40);
v[5] = new Vector2(-40, -40);
SetPolygonColliderPoints(v);
}
public void OnPointerClick(PointerEventData eventData)
{
//這裏做一些鼠標點擊位置相對於Collider的位置處理
Vector2 local;
local.x = eventData.position.x - (float)Screen.width / 2.0f - rectTransform.localPosition.x;
local.y = eventData.position.y - (float)Screen.height / 2.0f - rectTransform.localPosition.y;
bool isIn = IsPointInPolygon(local, polygonCollider.points);
Debug.Log("看我有沒有點擊到你的Collider之內: " + isIn);
}
/// <summary>
/// 設置PolyCollider2D的頂點的位置
/// </summary>
/// <param name="vecs">Collider的頂點位置信息,最好按順序編排,3個頂點以上才能構成一個平面哦</param>
public void SetPolygonColliderPoints(Vector2[] vecs)
{
polygonCollider.points = vecs;
}
/// <summary>
/// 判斷鼠標點擊點是否在PolygonCollider2D之內
/// </summary>
/// <param name="point">鼠標點擊位置</param>
/// <param name="polygon">Collider的頂點位置信息</param>
/// <returns></returns>
public bool IsPointInPolygon(Vector2 point, Vector2[] polygon)
{
int polygonLength = polygon.Length;
int i = 0;
bool inside = false;
float pointX = point.x;
float pointY = point.y;
float startX, startY, endX, endY;
Vector2 endPoint = polygon[polygonLength - 1];
endX = endPoint.x;
endY = endPoint.y;
while (i < polygonLength)
{
startX = endX;
startY = endY;
endPoint = polygon[i++];
endX = endPoint.x;
endY = endPoint.y;
inside ^= (endY > pointY ^ startY > pointY) && ((pointX - endX) < (pointY - endY) * (startX - endX) / (startY - endY));
}
return inside;
}
}