creator2.2.0: 先初始化创建1000个sprite node放入对象池, 再从对象池中创建500个对象加入场景, 再使用nodepool的put方法删除100个对象,界面直接卡主几秒。
1赞
cc.Class({
extends: cc.Component,
properties: {
enemyPrefab: cc.Prefab,
enemyNodes: cc.Node,
},
// LIFE-CYCLE CALLBACKS:
onLoad() {
cc.director.getCollisionManager().enabled = true;
this.initNodePools();
},
onBtn1() {
for (let i = 0; i < 500; ++i) {
let node = this.createEnemy(this.enemyNodes);
node.x = require("GameUtils").randomNumber(-cc.winSize.width / 2, cc.winSize.width / 2);
node.y = require("GameUtils").randomNumber(-cc.winSize.height / 2, cc.winSize.height / 2);
}
let allNodes = this.enemyNodes.children;
setTimeout(() => {
let temp = [];
for (let i = 0; i < 100; ++i) {
let rand = require("GameUtils").randomNumber(0, allNodes.length - 1);
temp.push(rand);
}
cc.log('temp=' + temp);
console.time("onEnemyKilled");
for (let i = 0; i < temp.length; ++i) {
let node = allNodes[temp[i]];
this.onEnemyKilled(node);
}
console.timeEnd("onEnemyKilled");
}, 500);
},
/**
* 初始化对象池
*/
initNodePools() {
console.time("initNodePools");
this.enemyPool = new cc.NodePool('enemy');
for (let i = 0; i < 1000; ++i) {
let node = cc.instantiate(this.enemyPrefab); // 创建节点
this.enemyPool.put(node); // 通过 put 接口放入对象池
}
console.timeEnd("initNodePools");
},
createEnemy(parentNode) {
let enemy = null;
if (this.enemyPool.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
enemy = this.enemyPool.get();
} else { // 如果没有空闲对象,也就是对象池中备用对象不够时,我们就用 cc.instantiate 重新创建
enemy = cc.instantiate(this.enemyPrefab);
}
enemy.parent = parentNode; // 将生成的敌人加入节点树
enemy.getComponent('Enemy').init(); //接下来就可以调用 enemy 身上的脚本进行初始化
return enemy;
},
onEnemyKilled: function (enemy) {
// enemy 应该是一个 cc.Node
//enemy.x = 10001;
this.enemyPool.put(enemy); // 和初始化时的方法一样,将节点放进对象池,这个方法会同时调用节点的 removeFromParent
}
});
卡主时间: onEnemyKilled: 2613.4677734375ms
我没有测试之前的版本是否也是这样,还是我的写法有问题?
我发现实质是: 先创建很多对象node, 然后再设置其中一些node.active = false; 这一步操作就很费时间。
这个问题我们会在 2.2.1 优化,谢谢反馈!
谢谢大佬的回复! 好像这个我试了之前的版本也是这样的,就是随便创建500个简单的Sprite对象, 然后隐藏其中50个对象, 就会卡一下。
上面实验中我的每个对象都有一个boxcollider, 所以导致node.active = false的时候很卡, 去掉boxcollider后就不卡了。。。
调用active就会卡,不要active
我实验出主要是boxcollider引起的, 绑定了boxcollider的对象node.active=false, 性能不行, 随便创建100个对象,然后设置隐藏就卡主了; 去掉boxcollider后,瞬间流畅了。
还有个坑,是成千个node active 的时候也会卡
说说我的经验吧,都是collider的锅,任何改变collider状态的操作,包括enabled, node active, 修改parent, 更改group都会引起严重的卡顿,试下来的方案是poolMgr 把对象放在看不见的地方,且collider不要有碰撞,否则也有性能问题
1赞
是的, BoxCollider问题很严重, 反而用物理系统里的collider性能还好些, 不过我现在准备自己写代码检测碰撞了。
嗯嗯,我这边只是简单的矩形碰撞检测,比较容易。