Array of templates (pool)

I am trying to make a pool of elements, i have a template that is instantiated and put into pool
like this:

PoolManager.prototype.initialize = function () {

    let app = this.app;
    let template = app.assets.get(this.assetId);

    for (let i = 0; i < this.itemCount; i++) {

        let instance = template.resource.instantiate();
        instance.script.reelElementController.Prepare();
        instance.setLocalPosition(new pc.Vec3(0, 0, 0));
        this.container.addChild(instance);
        pool.push(instance);
        // instance.enabled = false;
    }

    console.log(pool.length);
};

at the end console prints accurate items in the pool
every template has a script on it
the problem is when i want to access script it doesn’t let me

PoolManager.prototype.create = function () {

    let item;
    if (pool.length) {
        item = pool.shift();
        item.script.reelElementContoller.Test();
    }
    else {
        let template = this.app.assets.get(this.assetId);
        item = template.resource.instantiate();
        item.script.Prepare();
    }

    this.Info();
    return item;
};

so the question is how to access script on object that is in the pool?
this is common in unity it should be in playcanvas as well (sorry if this is beginner question, i am not expert in javascript)

i get this error

Uncaught TypeError: Cannot read properties of undefined (reading 'Test')

Hi @mirkoni,

Is pool a global variable? Your code seems correct, thinking can you try enabling the instance first, so the script instance initializes?

If you don’t manage to solve this, try posting a sample project link to take a look at.

here is the complete poolManager script

var PoolManager = pc.createScript('poolManager');

PoolManager.attributes.add('container', { type: 'entity' });
PoolManager.attributes.add('assetId', { type: 'number', default: 68783156 });
PoolManager.attributes.add('itemCount', { type: 'number', default: 100 });

const pool = [];

PoolManager.prototype.Info = function () {
    console.log("length: " + pool.length);
};

PoolManager.prototype.create = function () {

    this.Info();
    let item;
    if (pool.length) {
        item = pool.shift();
        console.log(typeof item);
        console.log(item.name);
        item.script.reelElementContoller.Test();
    }
    else {
        let template = this.app.assets.get(this.assetId);
        item = template.resource.instantiate();
        item.script.reelElementContoller.Prepare();
    }


    return item;
};

PoolManager.prototype.delete = function (item) {
    item.parent.removeChild(item);
    item.script.Reset();
    pool.push(item);

};

// pool[i].script.reelElementContoller.Prepare();
// initialize code called once per entity
PoolManager.prototype.initialize = function () {


    let app = this.app;
    let template = app.assets.get(this.assetId);

    for (let i = 0; i < this.itemCount; i++) {

        let instance = template.resource.instantiate();
        instance.script.reelElementController.Prepare();
        instance.setLocalPosition(new pc.Vec3(0, 0, 0));
        this.container.addChild(instance);
        pool.push(instance);

        console.log(typeof instance + "|" + typeof pool[i]);
        // instance.enabled = false;
    }

    console.log(pool.length);
};

// update code called every frame
PoolManager.prototype.update = function (dt) {

};

// swap method called for script hot-reloading
// inherit your script state here
// PoolManager.prototype.swap = function(old) { };

// to learn more about script anatomy, please read:
// http://developer.playcanvas.com/en/user-manual/scripting/

in initialize method it fills out the array with template objects and uses Prepare method on the script that is on the template, i can see it in the scene (it’s not disabled) but cant be accessed

Try debugging the reelElementController script instance, each time you spawn an entity, if that script is added and initialized.

in Initialize method where pool is populated i access Prepare method on the reelElementController and it’s propery accessed

reelElementController is on the template already (like prefabs in unity) it’s not added in runtime

Sorry it’s not easy to debug this out of context, seems more likely a JS reference issue. If you can provide a sample project that reproduces the issue, most likely it’s only a couple of minutes to debug it.

here it is https://playcanvas.com/editor/project/872694

How do I reproduce your error? Launching main scene seems to be working:

oh yes
pressing A on the keyboard tries to spawn from pool

Here is the error:

item.script.reelElementContoller.Test();

It should be:

item.script.reelElementController.Test();

Controller was missing an r.

4 Likes

jesus…

thank you, i am used to visual studio/rider hihi

1 Like