欢迎阅读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组件系列
分享地址
- Github :https://github.com/ll4080333/UnityCodes
- CSDN : http://blog.csdn.net/qq_29579137
如果你想了解UGUI的更多拓展组件,欢迎关注我的博客,我会持续更新,支持一下我这个博客新手。如果以上文章对你有帮助,点个赞,让更多的人看到这篇文章我们一起学习。如果有什么指点的地方欢迎在评论区留言,秒回复。