[SOLVED] [TS] Loading Prefabs directly from Cache


#1

Loading prefab(s) on for example startup where you need all prefabs isn’t hard:

cc.loader.loadResDir('url/to/my/prefabs/', cc.Prefab, (current, total) => {
  /* Progress */
}, (err, prefabs: cc.Prefab[]) => {
  /* Completed */
  this.node.addChild(cc.instantiate(prefabs[0]));
});

Or single prefab with cc.loader.loadRes(...)

But every time you need to access these prefabs and addChild() them to another node you have to go through the whole cc.loader-process?

I know the prefabs do load from cache the second time, but since they are already loaded I wouldn’t like to go through the whole asynchronous cc.loader-process. Instead use something like this:
cc.textureCache.getTextureForKey("hello.png"); but for .prefab

Is there something I’m missing for the prefabs that are similar to textureCache for images?
http://www.cocos2d-x.org/docs/creator-api/en/classes/textureCache.html?h=texturecache


#2

try cc.loader.getRes(url)


#3

Thank you for your answer! This is a way smarter way to re-load the already loaded prefab. But I still have a heavy memory leak in the game due to loading a lot of prefabs all the time.

I guess I have to either use cc.loader.release() or save the prefab somehow available for me throughout the software. I would not like to release it, rather re-use the same, but getRes() seems to create an own instance of it again, hence the memory leak.


#4

No, it doesn’t create new instance again, actually even when you call cc.loader.loadRes on already loaded resource it just gets it from cc.loader.getRes and return to you through callback in async manner


#5

Aah, cool! Thanks @persy.

I will check this out today. I think it’s the recursive creating of cc.instantiate() in the this.node.addChild(cc.instantiate()) that fills up my memory.

I cannot destroy children (that is prefabs) cause then I cannot re-use the prefabs again. If I just remove it I will get crazy memory leaks with creating new instances of the prefab with the cc.instantiate()


#6

Well, you should :slight_smile:

var node = cc.instantiate(prefab);
node.destroy();    // prefab is fine, you destroyed a cc.Node that was a copy
var node2 = cc.instantiate(prefab);    // works fine

#7

@persy I’ve tried destroy(); and destroyAllChildren(); on the node holding my prefab created with cc.instantiate(prefab);

If I destroy() in code just before I instantiate() i think it also destroys the new instantiate node/prefab, because everything disappears. Anyhow, I found a good way to destroy() and instantiate() + addChild() but the memory leak is still there. It doesn’t clear the cache even with destroy().

It is instantiate() that leaks memory. How do I clear the cc.instantiate() cache?