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类画一个矩形

渐变色描边源码下载

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 34
    评论
除了修改材质的方法Unity中还有其他方法可以实现颜色渐变。其中一种方法是使用Shader中的属性来实现颜色渐变,具体步骤如下: 1. 创建一个新的Shader:在Unity编辑器中,选择菜单栏的“Assets” -> “Create” -> “Shader”,创建一个新的Shader。 2. 编写Shader代码:在新的Shader中,使用“Properties”定义需要修改的颜色属性,使用“SubShader”定义需要渲染的对象,使用“CGPROGRAM”和“ENDCG”包裹渲染的代码。具体代码如下: ```csharp Shader "Custom/ColorGradientShader" { Properties { _Color ("Color", Color) = (1,1,1,1) } SubShader { Tags {"Queue"="Transparent" "RenderType"="Transparent"} Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; float3 worldPos : TEXCOORD0; }; float4 _Color; v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; return o; } fixed4 frag (v2f i) : SV_Target { float t = sin(_Time.y) * 0.5 + 0.5; fixed4 col = lerp(fixed4(1,0,0,1), fixed4(0,0,1,1), t); return col * _Color; } ENDCG } } FallBack "Diffuse" } ``` 以上代码定义了一个颜色属性“_Color”,并在片段着色器中使用了该属性和时间信息来实现颜色渐变。 3. 创建一个新的材质:在Unity编辑器中,选择菜单栏的“Assets” -> “Create” -> “Material”,创建一个新的材质。在材质的Inspector视图中,将刚才创建的Shader赋值给材质。 4. 将材质应用到对象上:在Hierarchy视图中选择需要渲染的对象,然后在Inspector视图中选择渲染器组件,将刚才创建的材质拖拽到渲染器组件的“Material”属性中。 以上步骤完成后,对象的颜色将会根据时间变化渐变。请注意,这里的颜色渐变是在Shader中实现的,而不是修改材质的颜色属性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周周的Unity小屋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值