本人未使用CocosCreator发布线上项目,未经线上验证,仅供大家学习,目前暂不从事CocosCreator工作。
Cocos Creator 控制合批主要是在Batch2D中实现,检测的是(同一图集,同一材质,同一内存等),那么只要我们在提交前将数据搞成统一就好了。
function isInstanceOfAny(obj: any, types: any[]) {
return types.some(type => obj instanceof type);
}
const SupportComponents = [cc.SpriteFrame, cc.Label];
const UIRenderer = cc.js.getClassByName(`cc.UIRenderer`);
//更新材质
UIRenderer.prototype[`updateMaterial${_}`] = UIRenderer.prototype.updateMaterial;
UIRenderer.prototype.updateMaterial = function () {
//自动使用多图集合批材质
if (!this._customMaterial
&& !this._bNotMultiAtlas
&& isInstanceOfAny(this, SupportComponents)
&& fw.multiAtlasesMaterial) {
this.customMaterial = fw.multiAtlasesMaterial;
return;
}
this[`updateMaterial${_}`]();
}
//更新渲染数据
UIRenderer.prototype[`updateRenderer${_}`] = UIRenderer.prototype.updateRenderer;
UIRenderer.prototype.updateRenderer = function () {
this[`updateRenderer${_}`]();
//材质是否正确
if (!this._customMaterial
|| !fw.multiAtlasesMaterial
|| this._customMaterial != fw.multiAtlasesMaterial) {
return;
}
let nTexIndex: number;
const self: unknown = this;
if (nIndex < nMaxIndex) {
let dataHash: number;
if (self instanceof cc.Sprite) {
if (!self.spriteFrame) { return; }
let tex: cc.__private._cocos_asset_assets_texture_base__TextureBase;
dataHash = self.spriteFrame.texture.getHash();
if (cache.has(dataHash)) {
nTexIndex = cache.get(dataHash);
hashFunc(self.renderData);
} else {
self.customMaterial.setProperty(`texture${nIndex}`, self.spriteFrame.texture);
cache.set(dataHash, nIndex);
hashFunc(self.renderData);
nTexIndex = nIndex;
++nIndex;
}
} else if (self instanceof cc.Label) {
let tex: cc.__private._cocos_asset_assets_texture_base__TextureBase;
if (self.ttfSpriteFrame) {
tex = self.ttfSpriteFrame.texture;
dataHash = tex.getHash();
} else {
if (self.spriteFrame) {
if (self.spriteFrame instanceof cc.SpriteFrame) {
tex = self.spriteFrame.texture;
dataHash = tex.getHash();
} else {
//清理材质
this._customMaterial = null;
//标记
this._bNotMultiAtlas = true;
//刷新材质
this.updateMaterial();
}
}
}
if (dataHash) {
if (cache.has(dataHash)) {
nTexIndex = cache.get(dataHash);
hashFunc(self.renderData);
} else {
self.customMaterial.setProperty(`texture${nIndex}`, tex);
cache.set(dataHash, nIndex);
hashFunc(self.renderData);
nTexIndex = nIndex;
++nIndex;
}
}
} else {
console.warn(`暂不支持该类型多图集合批`, self);
}
} else {
nTexIndex = nNoneIndex;
}
if (nTexIndex != V0) {
if (self instanceof cc.Sprite) {
if (self.type == cc.Sprite.Type.SLICED) {
for (let i = 0, uv = this.spriteFrame.uvSliced; i < uv.length; ++i) {
uv[i].u = nTexIndex * 1000 + uv[i].u % 1000;
}
}
}
for (let i = 0, j = 3, r = this.renderData, v = r.chunk.vb; i < r.vertexCount; ++i, j += r.floatStride) {
v[j] = nTexIndex * 1000 + v[j] % 1000;
}
}
}
上面算是正确代码也算是伪代码,由于牵扯的东西也不少,我删减了,只留下了核心思想部分。