scrollview中避免item间不同节点交叉导致drawcall调用过高

scrollview中避免item间不同节点交叉导致drawcall调用过高

记录creator中scrollview多个item节点交叉导致导致drawcall调用过高的优化方案

产生的原因

在creator中,相邻且勾选了cachemode的label或者相邻且在同一图集里的sprite会合并渲染,并且只会调用一次draw call 如图:
在这里插入图片描述

在这里插入图片描述
三个sprite节点和三个label相邻,各自只调用了一次drawcall。而如果这几个节点交叉:
在这里插入图片描述

在这里插入图片描述
每个label和sprite都会调用一次draw call。

优化策略

在实际scrollview中,item在content节点下,多个item一般结构如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200807152432819.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2g4NzU0NTY0NQ==,size_16,color_FFFFFF,t_70

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200807153630346.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2g4NzU0NTY0NQ==,size_16,color_FFFFFF,t_70

可以看到,除去场景和scrollview的2次draw call,3个item共调用了6次。如果我们可以把一个item预制按label,同一图集的sprite拆分成多个,再依次instantiate并设置其zindex,就可以将label和同一图集的sprite在content下相邻排放。如:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200807153146494.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2g4NzU0NTY0NQ==,size_16,color_FFFFFF,t_70

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200807153449499.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2g4NzU0NTY0NQ==,size_16,color_FFFFFF,t_70

这样除去场景和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地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值