版权声明:本文为原创文章,转载请声明https://www.cnblogs.com/unityExplorer/p/13524270.html
自从UGUI出现之后,我就已经放弃使用NGUI了,原因不多说,毕竟是亲爹产的
不过即使如此,UGUI也存在不少问题,很多组件也不完善
今天要说的就是Outline这个组件,相信不少朋友都使用过,也相信不少朋友都和我一样,对于这个组件十分恶心
比如,我们给下面这张图添加一个描边
![](https://i-blog.csdnimg.cn/blog_migrate/984acb1fe20fb681ae0e22b8277e38e2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3bff066623596e1f11e0bba042cdb3d9.png)
诶,效果还不错哦,我们再换一张
![](https://i-blog.csdnimg.cn/blog_migrate/91070bb8a43d04c241c886d19bcb6495.png)
![](https://i-blog.csdnimg.cn/blog_migrate/77137e01e5923d514a9de7d8b074c681.png)
恩,我觉得应该没有美工能接受这样的描边,就算你叫他美术都不好使
这个问题要解决,怎么办好呢?我们先来分析分析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最为合适,效果如下
![](https://i-blog.csdnimg.cn/blog_migrate/bd1366afbb28ade5a49d782922e37240.png)
对于边缘圆滑的图片,修改bevelAngleCoefficient值也能达到比较好的效果
![](https://i-blog.csdnimg.cn/blog_migrate/31f908e18683fe1df8187a89fc840114.png)
![](https://i-blog.csdnimg.cn/blog_migrate/139ff5379d11a416904f961315654c1c.png)