Unity实现UGUI空物体颜色渐变的描边方法

一、关于UGUI的描边

在这里插入图片描述

当我们有如上图的描边需求时,可以考虑使用Unity原生自带两个组件的Outline和Shadow实现对于UI的描边,但是弊端还是很大的,因为这个两组件会造成顶点数和三角面数加倍,导致就是很耗电脑性能!而且挂载到UI空物体上是没有描边效果的。我们只能另寻他法,UGUI为我们提供了一个类MaskableGraphic帮助我们可以自定义重构UI组件,下面将演示如何重写其 OnPopulateMesh方法绘制线框。

二、重写OnPopulateMesh实现UI空物体描边

说是实现UI空物体的描边可能有点不准确,应该是给不继承于Graphic类的组件描边,因为一个游戏对象只允许拥有一个Graphic组件。像image和button等这种就不能添加这个脚本绘制描边,只能给这些组件添加空物体作为父物体,再将该描边脚本拖拽给空物体实现描边。

原理解析

在这里插入图片描述
注意:设置顶点位置是相对于UI锚点来确定的,如果锚点pivot=(0.5,0.5),那么UI顶点原点(0,0)就在UI中心点;如果锚点pivot=(0,0),那么UI顶点原点(0,0)在UI左下角。其中依次类推。
上图中,脚本里rectTransform.rect.width和height表示该ui空物体的宽高,即width=100,height=100。锚点为(0.5,0.5)所以:
(1)顶点1:quad1[0].positon=(-50,50,0)即UI左上角位置①处
(2)顶点2:quad1[1].positon=(50,50,0)即UI右上角位置②处
(3)顶点3:quad1[2].positon=(50,49,0)即UI右上角下方一个线宽像素位置③处
(4)顶点4:quad1[3].positon=(-50,49,0)即UI左上角下方一个线宽像素位置④处。
最后调用vh.AddUIVertexQuad(quad1)方法,将一个面片顶点信息添加进去,它就帮我们绘制出来下图的矩形线框了:
在这里插入图片描述
接下来我们就寻找规律,依次类推将其他线框绘制出来,实现一个可以将UI组件描边的效果啦。

完整代码实现

/// <summary>
/// UI空物体描边
/// </summary>
public class UIoutline : MaskableGraphic
{
    
    
    public Color lineColor = Color.black;//默认描边颜色
    public float lineWidth = 1f;//默认绘制的线宽,表示一个像素宽

    protected override void OnPopulateMesh(VertexHelper vh)
    {
    
    
        base.OnPopulateMesh(vh);
        vh.Clear();
        //定义边框的面片数组,表示面片的四个顶点。根据顶点顺序进行顺时针绘制
        UIVertex[] quad1 = new UIVertex[4];
        quad1[0] = new UIVertex();
        quad1[0].color = lineColor;
        quad1[0].position = new Vector3(-rectTransform.rect.width * 0.5f, rectTransform.rect.height * 0.5f, 0);
        Debug.Log(quad1[0].position);
        quad1[0].uv0 = Vector2.zero;

        quad1[1] = new UIVertex();
        quad1[1].color = lineColor;
        quad1[1].position = new Vector3(rectTransform.rect.width * 0.5f, rectTransform.rect.height * 0.5f, 0);
        quad1[1].uv0 = Vector2.zero;

        quad1[2] = new UIVertex();
        quad1[2].color = lineColor;
        quad1[2].position = new Vector3(rectTransform.rect.width * 0.5f, rectTransform.rect.height * 0.5f - lineWidth, 0);
        quad1[2].uv0 = Vector2.zero;

        quad1[3] = new UIVertex();
        quad1[3].color = lineColor;
        quad1[3].position = new Vector3(-rectTransform.rect.width * 0.5f, rectTransform.rect.height * 0.5f - lineWidth, 0);
        quad1[3].uv0 = Vector2.zero;
        vh.AddUIVertexQuad(quad1);

        UIVertex[] quad2 = new UIVertex[4];
        quad2[0] = new UIVertex();
        quad2[0].color = lineColor;
        quad2[0].position = new Vector3(-rectTransform.rect.width * 0.5f, -rectTransform.rect.height * 0.5f + lineWidth, 0);
        quad2[0].uv0 = Vector2.zero;

        quad2[1] = new UIVertex();
        quad2[1].color = lineColor;
        quad2[1].position = new Vector3(rectTransform.rect.width * 0.5f, -rectTransform.rect.height * 0.5f + lineWidth, 0);
        quad2[1].uv0 = Vector2.zero;

        quad2[2] = new UIVertex();
        quad2[2].color = lineColor;
        quad2[2].position = new Vector3(rectTransform.rect.width * 0.5f, -rectTransform.rect.height * 0.5f, 0);
        quad2[2].uv0 = Vector2.zero;

        quad2[3] = new UIVertex();
        quad2[3].color = lineColor;
        quad2[3].position = new Vector3(-rectTransform.rect.width * 0.5f, -rectTransform.rect.height * 0.5f, 0);
        quad2[3].uv0 = Vector2.zero;
        vh.AddUIVertexQuad(quad2);

        UIVertex[] quad3 = new UIVertex[4];
        quad3[0] = new UIVertex();
        quad3[0].color = lineColor;
        quad3[0].position = new Vector3(-rectTransform.rect.width * 0.5f, rectTransform.rect.height * 0.5f, 0);
        quad3[0].uv0 = Vector2.zero;

        quad3[1] = new UIVertex();
        quad3[1].color = lineColor;
        quad3[1].position = new Vector3(-rectTransform.rect.width * 0.5f + lineWidth, rectTransform.rect.height * 0.5f, 0);
        quad3[1].uv0 = Vector2.zero;

        quad3[2] = new UIVertex();
        quad3[2].color = lineColor;
        quad3[2].position = new Vector3(-rectTransform.rect.width * 0.5f + lineWidth, -rectTransform.rect.height * 0.5f, 0);
        quad3[2].uv0 = Vector2.zero;

        quad3[3] = new UIVertex();
        quad3[3].color = lineColor;
        quad3[3].position = new Vector3(-rectTransform.rect.width * 0.5f, -rectTransform.rect.height * 0.5f, 0);
        quad3[3].uv0 = Vector2.zero;
        vh.AddUIVertexQuad(quad3);

        UIVertex[] quad4 = new UIVertex[4];
        quad4[0] = new UIVertex();
        quad4[0].color = lineColor;
        quad4[0].position = new Vector3(rectTransform.rect.width * 0.5f - lineWidth, rectTransform.rect.height * 0.5f, 0);
        quad4[0].uv0 = Vector2.zero;

        quad4[1] = new UIVertex();
        quad4[1].color = lineColor;
        quad4[1].position = new Vector3(rectTransform.rect.width * 0.5f, rectTransform.rect.height * 0.5f, 0);
        quad4[1].uv0 = Vector2.zero;

        quad4[2] = new UIVertex();
        quad4[2].color = lineColor;
        quad4[2].position = new Vector3(rectTransform.rect.width * 0.5f, -rectTransform.rect.height * 0.5f, 0);
        quad4[2].uv0 = Vector2.zero;

        quad4[3] = new UIVertex();
        quad4[3].color = lineColor;
        quad4[3].position = new Vector3(rectTransform.rect.width * 0.5f - lineWidth, -rectTransform.rect.height * 0.5f, 0);
        quad4[3].uv0 = Vector2.zero;
        vh.AddUIVertexQuad(quad4);
    }
}

完整描边效果

在这里插入图片描述

三、拓展功能(渐变色的UI描边)

我们只需要根据自己的需求修改绘制线框时顶点的颜色就可以实现渐变色的效果了。
在这里插入图片描述

两种渐变色描边

我们只需要再添加一种颜色属性,设置顶点颜色时赋值不同颜色值即可得到上图左边红黑渐变描边效果。
脚本修改如下,其他顶点依次类推设置。
在这里插入图片描述

多种渐变色描边

添加另外三种颜色属性,设置顶点颜色时赋值不同颜色值即可得到上图右边红黄蓝绿渐变描边效果。
脚本修改如下,其他顶点依次类推设置,可在面板修改颜色属性查看不同渐变色效果。
在这里插入图片描述

四、推荐阅读

Unity在UI上使用MaskableGraphic类画一个矩形

渐变色描边源码下载

猜你喜欢

转载自blog.csdn.net/qq_42437783/article/details/124724638