Unity自定义UI组件(七)渐变工具、渐变色图片、渐变遮罩

欢迎阅读Unity自定义UI组件(七)渐变工具、渐变色图片、渐变遮罩

前言

在Unity中UGUI只为我们提供了最为基础的Image和RawImage两种可展示图片的组件,但是这两种组件要展示一些特殊效果的时候总是会依赖外界资源(PhotoShop资源),比如你想要一个简单的颜色渐变变色的文字 都会比较棘手,但是我们可以利用程序来解决这点小缺陷,我们可以编写自己的高级Image工具来实现Image和RawImage不具备的功能。

其实博主实在编写颜色拾取器的时候利用到了这个功能,觉得还蛮有意思、也蛮实用的就来分享给大家,也给大家一讲创建颜色拾取器先做一点基础准备。代码很短, 100行左右,但是可以实现很多有意思的功能。

目录

实现效果

废话少说,先看效果图

  • 原图
    原图
  • 特效图
    特效图
  • 其他效果一
    文字特效
  • 其他效果二
    这里写图片描述

主要内容

  • 实现绘制渐变色图片(多色可自定义)
  • 实现渐变方向的控制(垂直方向、水平方向)
  • 实现外边框(可选、颜色可选,粗细可选)

详细设计

绘制原理

Unity中UI的现实也是基于三角面的绘制,三角面是绘制的最小单位,比如给出三个顶点,即可绘制出一个三角形。一个矩形的绘制是由两个三角面拼合而成,三角面三个顶点应该逆时针绘制,逆时针绘制是朝着屏幕可见,顺时针绘制是逆着屏幕可见。每个顶点除了位置还带有其他属性比如颜色值,UV值(控制贴图),法线方向,我们这里用到最基础的就是位置和颜色值,应为不需要赋值贴图对UV值就不需要赋值,法线更多使用在Mesh编程中,模型若是没有法线,显示效果就会很糟糕,我一会也会推出更多的Mesh编程得内容。
UIVertex文档传送门
 渲染简图
逆时针三角面渲染顶点顺序:012 230
顺时针三角面渲染顶点顺序:021 320

具体设计

  • 绘制渐变色图片
    在UGUI中实现自定义绘制图形得继承至Graphic类型或是MaskableGraphic,这取决于你是否需要你自定的图形是可遮罩的,我们的类型继承至MaskableGraphic,然后重写其中的OnPopulateMesh(VertexHelp)进行绘制。
    VertexHelper文档传送门
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        //调用父类GetPixelAdjusteRect方法获取组件尺寸,如果是从RectTransform直接获取将不具备自适应的功能,因为调整锚点,组件尺寸会改变,从而不能达到自适应效果
        _rectSize = GetPixelAdjustedRect().size;
        //清除顶点流数据,如果不操作这一步会导致自己编写的组件在绘制时出现bug,因为上一个组件的顶点流没有清除掉,遗留到当前组件,当前组件就会多对一部分的顶点进行绘制导致bug出现
        vh.Clear();
        //绘制方向分为两种垂直绘制和水平绘制,如果不这样做,可直接旋转图片
        if (TapeDirection == E_DrawDirection.Vertical) DrawVerticalColoredTape(vh);
        else DrawHorizontalColoredTape(vh);
        //绘制外边框
        if (Outline) DrawOutline(vh);
    }
  • 原理图
    原理图
    [SerializeField]
    private List<Color> m_Colors = new List<Color>() {Color.red,Color.magenta};

    private void DrawVerticalColoredTape( VertexHelper vh )
    {
        int colorNumber = m_Colors.Count;
        //原理图竖直方向一格的长度就是offset
        float offset = _rectSize.y / ( colorNumber -1);
        //获取四个第一个参加绘制的矩形的四个顶点
        Vector2 topLeftPos = new Vector2(-_rectSize.x / 2.0f , _rectSize.y / 2.0f);
        Vector2 topRightPos = new Vector2(_rectSize.x / 2.0f , _rectSize.y / 2.0f);
        Vector2 bottomLeftPos = topLeftPos - new Vector2(0 , offset);
        Vector2 bottomRightPos = topRightPos - new Vector2(0 , offset);
        for ( int i = 0 ; i < colorNumber - 1; i++ )
        {
            Color startColor = m_Colors[i];
            Color endColor = m_Colors[i + 1];
            var first = GetUIVertex(topLeftPos, startColor);
            var second = GetUIVertex(topRightPos, startColor);
            var third = GetUIVertex(bottomRightPos,endColor);
            var four = GetUIVertex(bottomLeftPos, endColor);
            //传入四个顶点进行绘制
            vh.AddUIVertexQuad(new UIVertex[] { first , second , third , four });
            //然后向下迭代顶点
            topLeftPos = bottomLeftPos;
            topRightPos = bottomRightPos;
            bottomLeftPos = topLeftPos - new Vector2(0 , offset);
            bottomRightPos = topRightPos - new Vector2(0 , offset);
        }
    }

    // 新建UIVertex
    private UIVertex GetUIVertex( Vector2 point , Color color0 )
    {
        UIVertex vertex = new UIVertex
        {
            position = point ,
            color = color0 ,
        };
        return vertex;
    }
  • 渐变方向的控制
    水平方向的绘制和垂直方向的原理相同,就是水平方向的绘制在设置顶点颜色和迭代顶点时有所不同
    private void DrawHorizontalColoredTape( VertexHelper vh )
    {
        详细的代码见GitHub
    }
  • 外边框设计
    外边框的代码也比较简单,只需要找好对应的顶点即可,这里提供一个封装的方法,只要提供一个矩形两端的两个顶点即可绘制一个矩形,通过封装算法的办法减少我们需要手动计算顶点的个数
    //基本属性
    [SerializeField]
    public bool Outline = false;
    [SerializeField]
    public float OuelineWidth = 1.0f;
    [SerializeField]
    public Color OutlineColor = Color.black;
    private void DrawOutline( VertexHelper vh )
    {
        详细的代码见GitHub
    }
    private UIVertex[] GetQuad( Vector2 startPos , Vector2 endPos , Color color0 , float LineWidth = 2.0f )
    {
        详细的代码见GitHub
    }

改进与拓展

  • 改进
    1.以上代码中对不同颜色都是按等比例划分的,可以插入一个比例属性值,对渐变色的比例进行控制
    2.水平方向绘制的代码部分可以剔除,可直接在RectTransform 组件中进行旋转
  • 拓展
    1.有了以上这段代码就可以用它来制作颜色拾取器中的渐变色条
    2.在阅读过UnityEngine.UI.Image的源码之后,我们可以重写Image并利用差值方法操作顶点,实现一些特殊动画,比如书本翻页的动画
    3.更多其他很好的想法,需要大家的加入

Unity自定义UI组件系列

分享地址

猜你喜欢

转载自blog.csdn.net/qq_29579137/article/details/72996996