文章目录
一. 前言
游戏开发中,可能有一些不规则按钮,而且必须严格检测不规则区域是否被点击到。一个常见的例子就是地图板块按钮。
二. 最终效果
注:有同学私信说没做出来,所以我把Demo
工程上传到GitHub
中了,感兴趣的同学可以下载来学习。GitHub
地址:https://github.com/linxinfa/Unity-UIPolygon-Demo
三. 实现
1、创建UICamera
创建一个Camera
,重命名为UICamera
,设置Culling Mask
为UI
,设置相机的投射模式(Projection
)为正交模式(Orthographic
),注意主摄像机的Culling Mask
去掉UI
层。Canvas
使用Screen Space - Camera
模式,并赋值UICamera
。
注意,UICamera
不需要Audio Listener
,直接去掉。
2. UIPolygon节点
在Button
的子节点创建一个空节点(这里重命名为UIPolygon
),挂上UIPolygon
脚本(脚本代码见文章最下面),会自动挂上Polygon Collider 2D
组件,将坐标归零。
3. 编辑碰撞区域
选中UIPolygon
节点,点击Polygon Collider 2D
组件中的Edit Collider
旁边的按钮,即可直接编辑多边形碰撞形状。
最后要调节Width
和Height
,确保包住整个不规则碰撞区域。
5. 运行测试
运行效果见文章开头。
6. UIPolygon代码
1 using UnityEngine; 2 using UnityEngine.UI; 3 #if UNITY_EDITOR 4 using UnityEditor; 5 #endif 6 7 [RequireComponent(typeof(PolygonCollider2D))] 8 public class UIPolygon : Image 9 { 10 private PolygonCollider2D _polygon = null; 11 private PolygonCollider2D polygon 12 { 13 get{ 14 if(_polygon == null ) 15 _polygon = GetComponent<PolygonCollider2D>(); 16 return _polygon; 17 } 18 } 19 20 //设置只响应点击,不进行渲染 21 protected UIPolygon() 22 { 23 useLegacyMeshGeneration = true; 24 } 25 26 protected override void OnPopulateMesh(VertexHelper vh) 27 { 28 vh.Clear(); 29 } 30 31 public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera) 32 { 33 return polygon.OverlapPoint( eventCamera.ScreenToWorldPoint(screenPoint)); 34 } 35 36 #if UNITY_EDITOR 37 protected override void Reset() 38 { 39 //重置不规则区域 40 base.Reset(); 41 transform.position = Vector3.zero; 42 float w = (rectTransform.sizeDelta.x *0.5f) + 0.1f; 43 float h = (rectTransform.sizeDelta.y *0.5f) + 0.1f; 44 polygon.points = new Vector2[] 45 { 46 new Vector2(-w,-h), 47 new Vector2(w,-h), 48 new Vector2(w,h), 49 new Vector2(-w,h) 50 }; 51 } 52 #endif 53 } 54 55 #if UNITY_EDITOR 56 [CustomEditor(typeof(UIPolygon), true)] 57 public class UIPolygonInspector : Editor 58 { 59 public override void OnInspectorGUI() 60 { 61 //什么都不写用于隐藏面板的显示 62 } 63 } 64 #endif
参考:http://www.xuanyusong.com/archives/3492