[SOLVED] [TS] Loading Prefabs directly from Cache

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

try cc.loader.getRes(url)

1 Like

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.

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

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()

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
1 Like

@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?

Hi guys. Do you have an example with cc.loader.getRes(url)? Because now I am using cc.loader.load(res,callback) and I have some problem after building. I’m getting the error that there are no prefab in res folder:
http://localhost:7456/build/res/raw-assets/resources/minigame_3.prefab

@Ronsku… Have you got the solution for your memory leaks issue ?

Yes, by using cc.NodePool();.

cc.instantiate(...) is a quite costly function and should only be used to generate a prefab once.

Thanks for the reply, i tried cc.NodePool() for create and release prefab but the memory it takes to create is not releasing at the time when i call ‘put()’ method of cc.NodePool() for destroying my created prefeb…