Unity实用功能之UGUI的Text实现颜色渐变详解(二)

2,549 阅读5分钟

这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战

概述

上一篇文章我们写到在unity中,想要更改Text为渐变色,那么就需要自己写一些功能,上一篇文章我们也大概的进行了一下分析,如何才能够实现text的颜色渐变,其原理就是更改Text顶点颜色,从而达到颜色渐变的功能,今天就来扩展下Text组件的功能,为其增加一个颜色渐变的功能,顺带添加一个阴影功能,有对text的顶点还不是很了解的可以去看一下我的上一篇文章“Unity实用功能之UGUI的Text颜色渐变详解(一)”,详细的请去本人的专栏查看。专栏地址

顶点分析

上一篇文章我们通过代码获取,知道了每一个字符有6个顶点,那么这些顶点的顺序又是什么呢?这个至关重要,因为这个涉及到我们颜色渐变的方向等。那么就让我们一起来看一下,这6个顶点是怎么的顺序。
通过下图我们可以看到,一个字符在Scene中只画出了四个顶点,那么就说明,其中必定有两个顶点是重合的。

image.png 一个文字有4个顶点,组成两个三角面。但是组成两个三角面时,有两个顶点会重复计数。我们通过Inspector中的网格可以看到,Text的每个字符是两个三角面,共6个顶点(包含两个相邻重复点)(实际只有4个顶点),每个字符的左上角和右下角两点是重复的。

image.png 所以我进行的测试,发现,这些顶点的顺序是从左上角开始的,结束也在左上角,如下图

image.png

渐变实现

顶点顺序我们也知道了,接下来就剩下了实现渐变了。这里我们以两种颜色渐变为例 首先定义一个枚举,选择一下渐变颜色的方向,这里面我定义了四种,横向,纵向,左上至右下,左下至右上

 public enum GradientDirection { Horizontal, Vertical,LeftUpToRightDown,LeftDownToRightUp }

接下来定义一下颜色和方向

public Color32 topColor = Color.white;//顶部颜色
public Color32 bottomColor = Color.black;//底部颜色
public GradientDirection gradientDirection;//渐变方向

接下来就是给顶点进行着色
首先来看一下颜色应该如何设置 这里我给分成了四种情况进行分析,代码中用到的是两种,另外两种也非常的简单

第一种

纵向渐变:条件需要两种颜色,下图蓝色箭头为渐变方向

image.png

通过上图我们可以看到,纵向渐变需要两种颜色,也就是说只要设置顶点0,1,5为一个颜色,顶点2,3,4为另一个颜色即可实现纵向颜色渐变

第二种

横向渐变:条件需要两种颜色,下图蓝色箭头为渐变方向 image.png 通过上图我们可以看到,横向渐变也是需要两种颜色即可,也就是说只要设置顶点1,2,3为一个颜色,顶点0,4,5为另一个颜色即可实现纵向颜色渐变

第三种

从左上至右下渐变:条件需要两种及以上颜色(左上一种颜色,中间一种颜色,右下一种颜色),下图蓝色箭头为渐变方向 image.png 通过上图我们可以看到,从左上至右下渐变需要至少两种颜色才能够实现,也就是说要设置顶点0,5为一个颜色,顶点1,4为另一个颜色,顶点2,3为第三种颜色(第三种颜色和第一种颜色相同),即可实现纵向颜色渐变

第四种

从左下至右上渐变:同第三种,条件需要两种及以上颜色(左下一种颜色,中间一种颜色,右上一种颜色),下图蓝色箭头为渐变方向 image.png 通过上图我们可以看到,从左下至右上渐变需要至少两种颜色才能够实现,也就是说要设置顶点4为一个颜色,顶点0,5,2,3为另一个颜色,顶点1为第三种颜色(第三种颜色和第一种颜色相同),即可实现纵向颜色渐变

代码实现

首先获取顶点个数和所有顶点,然后遍历,按照上述的分析,设置不同的颜色

int count = vertexBuffers.Count;
if (count > 0)
{
    /**给顶点着色( 这里需要明白顶点的顺序 )            
    *   5-0 ---- 1
    *    | \    |
    *    |  \   |
    *    |   \  |
    *    |    \ |
    *    4-----3-2
    **/
    for (int i = 0; i < count; i += DefautlVertexNumPerFont)
    {
        //分别设置每个顶点的颜色
        switch (gradientDirection)
        {
            //纵向
            case GradientDirection.Horizontal:
                ModifyVertexColor(vertexBuffers, i, topColor);
                ModifyVertexColor(vertexBuffers, i + 1, topColor);
                ModifyVertexColor(vertexBuffers, i + 2, bottomColor);
                ModifyVertexColor(vertexBuffers, i + 3, bottomColor);
                ModifyVertexColor(vertexBuffers, i + 4, bottomColor);
                ModifyVertexColor(vertexBuffers, i + 5, topColor);
                break;
            //横向
            case GradientDirection.Vertical:
                ModifyVertexColor(vertexBuffers, i, topColor);
                ModifyVertexColor(vertexBuffers, i + 1, bottomColor);
                ModifyVertexColor(vertexBuffers, i + 2, bottomColor);
                ModifyVertexColor(vertexBuffers, i + 3, bottomColor);
                ModifyVertexColor(vertexBuffers, i + 4, topColor);
                ModifyVertexColor(vertexBuffers, i + 5, topColor);
                break;
            //左上至右下
            case GradientDirection.LeftUpToRightDown:
                ModifyVertexColor(vertexBuffers, i, topColor);
                ModifyVertexColor(vertexBuffers, i + 1, bottomColor);
                ModifyVertexColor(vertexBuffers, i + 2, topColor);
                ModifyVertexColor(vertexBuffers, i + 3, topColor);
                ModifyVertexColor(vertexBuffers, i + 4, bottomColor);
                ModifyVertexColor(vertexBuffers, i + 5, topColor);
                break;
            //左下至右上
            case GradientDirection.LeftDownToRightUp:
                ModifyVertexColor(vertexBuffers, i, bottomColor);
                ModifyVertexColor(vertexBuffers, i + 1, topColor);
                ModifyVertexColor(vertexBuffers, i + 2, bottomColor);
                ModifyVertexColor(vertexBuffers, i + 3, bottomColor);
                ModifyVertexColor(vertexBuffers, i + 4, topColor);
                ModifyVertexColor(vertexBuffers, i + 5, bottomColor);
                break;
            default:
                break;
        }
    }                
}

额外增加添加阴影功能

   if (useEffect)//是否使用阴影(如果不需要阴影功能可以这部分代码删掉)
        {
            //扩充一倍的顶点容量
            var neededCapacity = vertexBuffers.Count * 2;
            if (vertexBuffers.Capacity < neededCapacity)
                vertexBuffers.Capacity = neededCapacity;

            for (int i = 0, cnt = vertexBuffers.Count; i < cnt; ++i)
            {
                var vt = vertexBuffers[i];
                vertexBuffers.Add(vt);

                Vector3 v = vt.position;
                v.x += effectDistance.x;
                v.y += effectDistance.y;
                vt.position = v;
                vt.color = effectColor;
                vertexBuffers[i] = vt;
            }
        }

实现效果

展示4.gif

写在最后

所有分享的内容均为作者在日常开发过程中使用过的各种小功能点,分享出来也变相的回顾一下,如有写的不好的地方还请多多指教。欢迎大家相互学习进步。本片文章就先写到这里,下一篇将继续介绍如何实现Text的颜色渐变

源代码地址

GitHub下载地址:github.com/ShuxinWen/U…