UGUI Outline实现原理分析

 

使用 UGUI 制作背包的时候,同事发现如果背包中添加了大量的物品,比如两百个,Unity就会出错,提示 Canvas element contains more than 65535 vertices. This is not supported 。意思就是 Canvas下面的顶点数过多。

如下图:

UGUI Outline

但是一个物品 的GameObject 难道有300个顶点不成?

不看不知道一看吓一跳,一个物品 居然有 500个Verts。

在对 物品的 GameObject 下面的子 物体 一个一个 禁用然后查看顶点后发现,当把Text 禁用之后,Verts 会锐减几百个。

 

没有禁用 Text 时的顶点数

UGUI Outline

禁用 Text 的顶点数

UGUI Outline

于是,继续,在Text 上发现挂了 Outline 组件,把Outline 禁用之后,发现Verts 锐减。才确定是 Outline的原因。

 

禁用Outline 之前

UGUI Outline

禁用Outline 之后

UGUI Outline

Ok,就是 Outline的原因。

 

那为什么Outline 会增加这么多顶点数呢?

查看UGUI的 Outline的源代码,如下:


using System.Collections.Generic;

namespace UnityEngine.UI
{
[AddComponentMenu("UI/Effects/Outline", 15)]
public class Outline : Shadow
{
protected Outline()
{}

public override void ModifyVertices(List<UIVertex> verts)
{
if (!IsActive())
return;

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

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

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

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

代码中的意思是 执行 ApplyShadow 4次,而且传过去的参数分别是 (x,y) (x,-y) (-x,y) (-x,-y) 。看到这四个值,好像感觉到了什么。。

来看看 这个函数做了什么。


protected void ApplyShadow(List<UIVertex> verts, Color32 color, int start, int end, float x, float y)
{
UIVertex vt;

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

for (int i = start; i < end; ++i)
{
vt = verts[i];
verts.Add(vt);

Vector3 v = vt.position;
v.x += x;
v.y += y;
vt.position = v;
var newColor = color;
if (m_UseGraphicAlpha)
newColor.a = (byte)((newColor.a * verts[i].color.a) / 255);
vt.color = newColor;
verts[i] = vt;
}
}

简单的就是说:

1、把原来的顶点 Copy出来一份,并且根据编辑器中设置的偏移量 来设置 Copy 出来的顶点的位置

2、根据编辑器中设置的 Shadow 颜色设置定点色

执行了4次,每一次都Copy了一份顶点。。这难道是 复制了4份 Text ?这和我们自己再另外添加 4个Text性质差不多吧。。

想到一个很好验证的方法,把偏移量设置的很大,我们来看看。

UGUI Outline

我们知道 1个字 = 1张图片 = 2个三角形 =4 个顶点。

本来用 Text ,定点数量就会比较多,而 Outline 却在这个 值上 乘以 5 。

所以,慎用 Outline,好了本篇unity3d教程到此结束,下篇我们再会!