在实际开发中我们经常会使用到动态加载图片,比如背包中加载道具Icon.下面我们做个例子,来看看drawcall消耗.
首先我们使用FairyGUI编辑器制作一个List,然后动态加载图片到List中去.
public UIPanel Panel;
void Start()
{
GList list = Panel.ui.GetChild("n0").asList;
list.itemRenderer = RenderListItem;
//创建18张图片
list.numItems = 18;
}
private void RenderListItem(int index, GObject obj)
{
GLoader loader = obj.asCom.GetChild("n0").asLoader;
//加载图片
NTexture texture = new NTexture(Resources.Load<Texture>("img" + index % 9));
loader.texture = texture;
}
上面可以看到,我一共添加了18张图片到List中去.但是其中每两张都是重复的,实际上我使用到的图片资源只有9张.一共有19个drawcall,其中天空盒占一张, 18张图片各占一张.但是我们只有9张图片是不一样的,那么根据Unity的动态合并规则应该是只占9个drawcall,这样明显是不合理的.我们的每个NTexture都会占用一个drawcall,所以我们应该缓存起NTexture,相同的图片就使用同一个NTexture,而不应该每次都new,这样既优化了drawcall,也优化了内存.
public UIPanel Panel;
//图片缓存
private Dictionary<string, NTexture> _textureDict = new Dictionary<string, NTexture>();
void Start()
{
GList list = Panel.ui.GetChild("n0").asList;
list.itemRenderer = RenderListItem;
//创建18张图片
list.numItems = 18;
}
private void RenderListItem(int index, GObject obj)
{
GLoader loader = obj.asCom.GetChild("n0").asLoader;
加载图片
//NTexture texture = new NTexture(Resources.Load<Texture>("img" + index % 9));
loader.texture = GetTexture("img" + index % 9);
}
private NTexture GetTexture(string name)
{
//从缓存中读取图片
if (_textureDict.ContainsKey(name)) return _textureDict[name];
//当缓存中没有图片,我们再加载
NTexture texture = new NTexture(Resources.Load<Texture>(name));
_textureDict.Add(name, texture);
return texture;
}
根据上面的代码,使我们重复利用了NTexture,所以我们得到的效果如下图:
现在可以看到18张图加上天空盒一共只占10个drawcall了.当然别忘记勾选UIPanel的FairyBatching,只有勾选了这个选项才能开起动态合并.