unity探索者之UGUI图片描边

版权声明:本文为原创文章,转载请声明https://www.cnblogs.com/unityExplorer/p/13524270.html

自从UGUI出现之后,我就已经放弃使用NGUI了,原因不多说,毕竟是亲爹产的

不过即使如此,UGUI也存在不少问题,很多组件也不完善

今天要说的就是Outline这个组件,相信不少朋友都使用过,也相信不少朋友都和我一样,对于这个组件十分恶心

比如,我们给下面这张图添加一个描边

 

诶,效果还不错哦,我们再换一张

 

  

 恩,我觉得应该没有美工能接受这样的描边,就算你叫他美术都不好使

这个问题要解决,怎么办好呢?我们先来分析分析UGUI中Outline的源码

    public class Outline : Shadow
    {
        protected Outline()
        {}

        public override void ModifyMesh(VertexHelper vh)
        {
            if (!IsActive())
                return;

            var verts = ListPool<UIVertex>.Get();
            vh.GetUIVertexStream(verts);

            var neededCpacity = verts.Count * 5;
            if (verts.Capacity < neededCpacity)
                verts.Capacity = neededCpacity;

            var start = 0;
            var end = verts.Count;
            ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, effectDistance.x, effectDistance.y);

            start = end;
            end = verts.Count;
            ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, effectDistance.x, -effectDistance.y);

            start = end;
            end = verts.Count;
            ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, -effectDistance.x, effectDistance.y);

            start = end;
            end = verts.Count;
            ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, -effectDistance.x, -effectDistance.y);

            vh.Clear();
            vh.AddUIVertexTriangleStream(verts);
            ListPool<UIVertex>.Release(verts);
        }
    }

代码很简单,也很好理解,通俗点说,就是把图片复制4份,然后叠在图片下方,每一张复制的图片都进行偏移,偏移量就是我们设置的描边的尺寸

既然原理是这样的,那问题简单了,我们增加复制的数量,将缺口补上就好了

    public class Outline : Shadow
    {
        public float bevelAngleCoefficient = 0.7071f; //1除以根号2

        public override void ModifyMesh(VertexHelper vh)
        {
            if (!IsActive())
                return;
            if (effectDistance.x == 0 && effectDistance.y == 0)
                return;

            var verts = ListPool<UIVertex>.Get();
            vh.GetUIVertexStream(verts);

            var neededCpacity = verts.Count * 9;
            if (verts.Capacity < neededCpacity)
                verts.Capacity = neededCpacity;

            float bevelAngleX = effectDistance.x * bevelAngleCoefficient;
            float bevelAngleY = effectDistance.y * bevelAngleCoefficient;

            var start = 0;
            var end = verts.Count;
            ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, effectDistance.x, effectDistance.y);

            start = end;
            end = verts.Count;
            ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, bevelAngleX, 0);

            start = end;
            end = verts.Count;
            ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, effectDistance.x, -effectDistance.y);

            start = end;
            end = verts.Count;
            ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, 0, bevelAngleY);

            start = end;
            end = verts.Count;
            ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, -effectDistance.x, effectDistance.y);

            start = end;
            end = verts.Count;
            ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, -bevelAngleX, 0);

            start = end;
            end = verts.Count;
            ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, -effectDistance.x, -effectDistance.y);

            start = end;
            end = verts.Count;
            ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, 0, -bevelAngleY);

            vh.Clear();
            vh.AddUIVertexTriangleStream(verts);
            ListPool<UIVertex>.Release(verts);
        }
    }
bevelAngleCoefficient是斜角系数,这个值的设定是为了满足不同类型的图片,边缘较圆滑的图片,使用默认值就可以,对于上面的叉,值设置为2最为合适,效果如下

 

对于边缘圆滑的图片,修改bevelAngleCoefficient值也能达到比较好的效果

 

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值