Unity3D:UGUI圆角矩形ImagePro(使用Shader实现,支持长方形)

关于圆角矩形image的实现,有很多方法。比如,重绘UI的Mesh、Shader实现。之前也写过相关的文章,今天要讲的是shader实现,和之前shader实现的方法有一些不一样,并且我写成一个UI组件,可以直接使用。

之前Shader是用RoundedRectangle节点实现的,这个虽然简单,但是有个缺点,就是只能是正方形的,长方形圆角就会变形。后来网上搜了一下,大部分也都是用RoundedRectangle节点实现的,后来问了DeepSeek,给出了另外一种解决方案,就是用图片的宽高计算四个角的圆角的中心点坐标,然后使用算法将四个圆角设置透明。这就是基本原理,下面直接上ShaderGraph的连线图。文章源自大腿Plus-https://www.zhaoshijun.com/archives/2082

Unity3D:UGUI圆角矩形ImagePro(使用Shader实现,支持长方形)文章源自大腿Plus-https://www.zhaoshijun.com/archives/2082

先说一下属性文章源自大腿Plus-https://www.zhaoshijun.com/archives/2082

1,MainTex:这个是固定的,是用来让UI的Image组件设置图片用的,不能更改文章源自大腿Plus-https://www.zhaoshijun.com/archives/2082

2,Radus:圆角半径,这个是圆角的大小,范围是0到最小边长的一半文章源自大腿Plus-https://www.zhaoshijun.com/archives/2082

3,Size:图片的宽高文章源自大腿Plus-https://www.zhaoshijun.com/archives/2082

在说一下Shader的连线的节点文章源自大腿Plus-https://www.zhaoshijun.com/archives/2082

1,先说最右边上面的MainTex属性连接的节点SampleTexture2D,这个节点主要是用来显示UI的Image上的Sprite图片的。名称是固定的。SampleTexture2D的Texture和MainTex属性连接,RGBA与BaseColor连接文章源自大腿Plus-https://www.zhaoshijun.com/archives/2082

2,然后下面的圆角相关节点(从左到右)文章源自大腿Plus-https://www.zhaoshijun.com/archives/2082

(1)UV节点:Out连接Subtract节点的A文章源自大腿Plus-https://www.zhaoshijun.com/archives/2082

(2)Subtract节点(1)节点:B连接一个Float的out,A连接UV节点,Out连接Absolute节点的In

(3)Float节点:Float节点的X是固定的0.5,Out连接Subtract节点(1)和(2)B

(4)Absolute节点:In连接Subtract节点,Out连接Subtract节点(2)的A

(5)Subtract节点(2)节点:B与Float节点Out连接,A与Absolute节点连接,Out连接Muktiply节点的B

(6)Multiply节点:A与Size属性连接,B与Subtract节点(2)的Out连接,Out与Add节点的A连接

(7)Add节点:A与Multiply节点的Out连接,B与Size属性连接,Out与Maximun节点的A连接

(8)Maximun节点:A与Add节点的Out连接,B的x和y为0,Out与Length节点的In连接

(9)Length节点:In与Maximun节点的Out连接,Out与Subtract节点(3)节点A连接

(10)Subtract节点(3)节点:A与Length节点的Out连接,B与Radius属性连接,Out与SmoothStep节点的In连接

(11)SmoothStep节点:In与Subtract节点(3)节点的Out连接,Edge1和Edge2分别是0和0.01,Out与OneMinus节点连接

(12)OneMinus节点:In与SmoothStep节点的Out连接,Out与Alpha连接

接下来就是用代码控制这些属性了,如果每次使用都要单独设置大小和圆角半径,就很麻烦,所以我就自己写了个ImagePro组件自动设置圆角半径和宽高。不管是Editor还是Runtime,都是自动设置的,包括在动态设置RectTransform大小。

我实现的方式是继承Image实现了自动添加材质和设置材质属性的方法,重写了UI的RectTransfrom改变的方法OnRectTransformDimensionsChange,去设置材质属性。并且重写了ImageEditor方法,在Editor下也能自动设置。在写这个组件的过程中遇到了一个小问题,就是在ShaderGraph把属性隐藏之后,Image的Sprite为Null的时候就会报一个找不到MainTex属性的错误,这个具体原因不太明白,其他隐藏的属性我在设置的时候也没有报错,唯独MainTex,后来我看Image源码,在Sprite为Null时,会执行UpdateMaterial方法,这个方法找到父类的实现,这时候会设置一个材质,并且设置一张默认白色图片,我猜可能这个时候出了某些问题导致报错。后来我重写了UpdateMaterial方法  在sprite为Null的时候重新设置了材质和图片,并且不执行父类的内容。好了,下面直接上代码。


下面是Editor代码。

在Editor代码中还增加了ImagePro组件的菜单项,可以自动生成ImagePro。
我的微信
微信扫一扫
weinxin
shijun_z
我的QQ
QQ扫一扫
weinxin
846207670
 最后更新:2025-3-26
大腿Plus
  • 本文由 大腿Plus 发表于 2025年3月20日 14:39:19
  • 转载请务必保留本文链接:https://www.zhaoshijun.com/archives/2082

发表评论