首先,我们先来看一个问题,如下图演示
当鼠标点击图片里正六边形内某个点时,我们需要取到该点的颜色值并进行一些操作。而点击正六边形外的透明区域时,我们不需要对该区域进行取值,但是Unity没有正六边形碰撞体,用其他碰撞体代替总会有一些问题。
于是,我首先想到了用多个小碰撞体来拼接一下,好了,问题完美解决了。
不过。。。如果是这样的呢?
要想完美拼接起来,那得需要多少boxcollider啊!
于是我又想到了另外一种方法:线性规划。
通过线性规划将所需区域围起来,点击时判断鼠标位置是否在规划区域里,从而解决不规则多边形的事件检测。
简单的做了一个Demo,部分代码如下:
直线类(相应的可以扩展各种曲线)
public class Line { public Vector2 StartPos { get; set; } public Vector2 EndPos { get; set; } public Line(Vector2 start, Vector2 end) { StartPos = start; EndPos = end; } /// <summary> ///计算点是否在该直线上 /// </summary> /// <param name="point"></param> /// <returns>0:点在直线上;1:点在直线上方;-1:点在直线下方</returns> public int IsOnLine(Vector2 point) { float yOnLine = CalcYByX(point.x); if (Math.Abs(yOnLine - point.y) <= 0.001f) return 0; else { if ((yOnLine - point.y) > 0) return -1; else return 1; } } public float CalcYByX(float x) { if (StartPos.x == EndPos.x) throw new Exception("X1=X2"); if (StartPos.y == EndPos.y) return StartPos.y; return (EndPos.y - StartPos.y) / (EndPos.x - StartPos.x) * (x - StartPos.x) + StartPos.y; } }
正六边形线性规划代码:
//线性规划解决点是否在正六边形内部 bool IsInRegularHexagon(Vector2 center,float edge,Vector2 point) { Vector2 pUp=new Vector2(center.x,center.y+edge); Vector2 pDown = new Vector2(center.x, center.y - edge); Vector2 pLeft1 = new Vector2(center.x-1.732f/2*edge, center.y + edge/2); Vector2 pLeft2=new Vector2(center.x-1.732f/2*edge, center.y - edge/2); Vector2 pRight1=new Vector2(center.x+1.732f/2*edge, center.y + edge/2); Vector2 pRight2=new Vector2(center.x+1.732f/2*edge, center.y - edge/2); Line line1 = new Line(pUp,pLeft1); Line line2 = new Line(pUp,pRight1); Line line3 = new Line(pDown,pLeft2); Line line4 = new Line(pDown,pRight2); if (point.x > (center.x - 1.732f / 2 * edge) && point.x < center.x + 1.732f / 2 * edge) { if (line1.IsOnLine(point)==-1&& line2.IsOnLine(point)==-1&& line3.IsOnLine(point)==1&& line4.IsOnLine(point)==1) { return true; } } return false; }