scrollview中避免item间不同节点交叉导致drawcall调用过高
记录creator中scrollview多个item节点交叉导致导致drawcall调用过高的优化方案
产生的原因
在creator中,相邻且勾选了cachemode的label或者相邻且在同一图集里的sprite会合并渲染,并且只会调用一次draw call 如图:
三个sprite节点和三个label相邻,各自只调用了一次drawcall。而如果这几个节点交叉:
每个label和sprite都会调用一次draw call。
优化策略
在实际scrollview中,item在content节点下,多个item一般结构如下:
可以看到,除去场景和scrollview的2次draw call,3个item共调用了6次。如果我们可以把一个item预制按label,同一图集的sprite拆分成多个,再依次instantiate并设置其zindex,就可以将label和同一图集的sprite在content下相邻排放。如:
这样除去场景和scrollview,items总共调用了2次draw call。
实际应用
定义需要拆分的item预制数组和对应zindex数组
// An highlighted block
@property({
tooltip: '拆分的item数组',
type : [cc.Prefab]
})
mulItemArray: Array<cc.Prefab> = new Array()
@property({
tooltip: '对应拆分的item在夫节点下的zindex',
type : [cc.Integer]
})
mulZIndexArray: Array<number> = new Array()
生成item时的代码:
// An highlighted block
/**
* 获得一个组合的item,先从poolList获取,如果没有则根据mulItemArray记录的item预制生成对应数量的item node设置zindex并返回node数组
*/
public getItemNode() : Array<cc.Node>{
let items = new Array()
//poolList是复用item逻辑,不用关心
if (this._poolList.length > 0) {
items = this._poolList.pop()
for (let i = 0; i < items.length; i++) {
items[i].active = true
items[i].opacity = 255
}
} else {
for (let i = 0; i < this.mulItemArray.length; i++) {
let item = cc.instantiate(this.mulItemArray[i])
item.parent = this._content
item.active = true
item.zIndex = this.mulZIndexArray[i] + this._combiantionItemCount
items.push(item)
}
this._combiantionItemCount ++
}
return items
}
参考代码
git地址