用NGUI实现增强版按钮遮罩

来源:互联网 发布:金星秀 知乎 编辑:程序博客网 时间:2024/06/05 20:13

前几天在某乎上翻到一篇老文章:新手引导按钮高亮后面有黑色蒙版使用NGUI应该怎么实现?。几位大神提出了好几种不同的做法。论效果我认为复制按钮最好,但是实现麻烦,消息传递更麻烦。我个人倾向于掏洞做法,因为遮罩的实现不对UI本身造成影响,有时候低耦合就是最大的优势。但是掏洞做法普遍非常简陋,有的就是拿几个盒子拼一个矩形的洞出来,因此我决定自己实现一个稍微强大一些的掏洞效果,花了几天时间做了一版,效果还不错,顺便也对NGUI的内部实现多了些了解,看来知识还是得从实践中来。

先说说我的设计目标:既然是基于NGUI,遮罩本身必须是一个UIWidget,我把它起名为UIMaskWidget。它t继承自UIWidget,拥有UIWidget的所有特性。普通的Widget的边框包裹区域就是它的显示区域,而MaskWidget的边框包裹区域则是它的洞,与普通Widget正好相反,边框外全部都是它的显示区域。同时遮罩支持显示纯色,也支持显示贴图,包括九宫格贴图。使用时只要把MaskWidget的Anchors锁定到目标按钮Widget上,它的洞就会始终和目标按钮的大小和位置保持一致,达到动态完美适配。

首先给出显示效果:如下图所示,Button1和Button2是两个一模一样的按钮,MaskWidget的锚点定位在Button1上,它的洞和Button1完全吻合,同时覆盖了背景和Button2,也阻挡了Button1区域外的触摸。


下面分析做法

颜色遮罩:实现方式参考UITexture的掏洞九宫格实现(不勾选Fill Center的Sliced Sprite),九宫格有内外两个矩形,我们把外矩形的4个顶点坐标设置为NGUI全屏区域的四个边角坐标,内矩形4个顶点就是Widget的边框顶点,然后得到周围一圈一共8个方块的顶点信息,在OnFill()函数里,把verts参数用这8个方块的4个顶点依次填充,一共是32个顶点,然后再把每个顶点的UV信息和顶点颜色也填充进参数,填充完毕后NGUI就会自动使用这些顶点数据绘制Mesh了。


物理遮罩:设置Collider就麻烦很多了,因为Collider必须在Widget上才会被NGUI正确检测,普通的Widget使用的都是Unity自带的BoxCollider,带洞的遮罩只能用MeshCollider实现了。那我们就用九宫格的8个顶点创建一个带洞的Mesh来作为MeshCollider的参数,该Mesh不负责显示,所以只需要填充顶点和三角形数据。如下图所示,该Mesh图形由8个三角形组成。把计算得到的顶点数组和三角形数组填充到Mesh里,然后创建一个MeshCollider组件并把Mesh传递给它即可。


还有贴图赋值、UV计算等内容,因为大多是从NGUI的代码里搬来的,就不介绍了,有兴趣的请自己参看代码吧。

源码下载(UnityPackage) 未包含NGUI,请先自行导入

原创粉丝点击