__attributes vs __attributesRaw

Right after cloning an entity, inside its initialize function, I’m trying to remap the references to the other entities assigned to the script’s attributes, down in the hierarchy of the clone object.

A (has a reference to B and C)
– B (has a reference to B1 and B2)
----B1
----B2
– C

When I clone A, I’m cycling through all its scripts and the scripts of its children.
But sometimes when I try to access a script attribute is not yet defined.

Looking inside the script instance I see that it happens then the __attributes is an empty object, while __attributesRaw contains the attributes I need to rewrite.

Here is a screenshot:

What is __attributesRaw and when __attributes is supposed to be ready?

So looking at the source of the engine it seems that __attributes is filled right before the initialize method.
Unfortunately, it means that B is not ready yet when the initialize method is called for A…
I’m spending already many hours trying to do a simple instancing of the same entity… :triumph:

I suggest that you don’t use Entity attributes in this case. If you need attributes then use a string to pass the child Entity’s name and then in your script in the initialize function find the child Entity by name.

It’s not more ‘efficient’ to use Entity script attributes - they just use findByGuid instead of findByName. You’re going to have a miserable time if you’re trying to change how cloning works for Entity script attributes yourself in the engine - it’s not easy.

I am for automating as much as possible, and adding a findByName in every single entity is really annoying…

I resolved the issue and I went even farther by adding a cloneEx method to the Entity class:

pc.Entity.prototype.cloneEx = function() {
    var c = this.clone();
    c.remapClonedEntity();
    return c;
};

pc.Entity.prototype.remapClonedEntity = function() {
    if (this.script) {
        var scripts = this.script.scripts;
        for (var i = 0; i < scripts.length; i++) {
            var script = scripts[i];
            var attrs = script.__scriptType.attributes.index;
            for (var attr in attrs) {
                if(!attrs.hasOwnProperty(attr)) continue;
                if (attrs[attr].type == 'entity') {
                    var attrPt = script.__attributesRaw[attr];
                    var newEntity = this.findByName(attrPt.name);
                    if (newEntity) {
                        script.__attributesRaw[attr] = newEntity;
                    } else {
                        console.log(this.name + '.' + attr + ' points to an non-child entity: ' + attrPt.name);
                    }
                }
            }
        }
    }
    for (var child in this.children) {
        // sometimes there is a NodeGraph as child zero... why???
        if (this.children[child].remapClonedEntity) this.children[child].remapClonedEntity();
    }
};