Issue with Undefined Render Information When Switching Scenes in PlayCanvas

Hello PlayCanvas Community,

I’ve been encountering a perplexing issue in my PlayCanvas project related to attributes and entity variables. I have defined some entity variables using attributes in order to switch their materials. Initially, when I enter the scene, everything works as expected. However, if I switch to another scene and then return to the original one, I find that the entity variables no longer have access to their render information, and I get “undefined” errors.

Here’s a bit more detail on the problem:

  1. I have a PlayCanvas scene where I define certain entity variables using attributes
  2. In the initialize method of my script, I’m setting up these entity variables and performing operations on them based on user interactions.
  3. When I first enter the scene, everything works as expected, and the entities are correctly manipulated.
  4. However, if I navigate to another scene within my PlayCanvas application and then return to the original scene, I notice that the entity variables defined in my script now return “undefined” when I try to access their render information (e.g., materials, meshInstances, etc.).

I’ve thoroughly checked my code for potential issues like variable scoping, script loading order, or scene transitions, but I can’t seem to pinpoint the exact cause of this problem. It only occurs when switching between scenes.

Has anyone encountered a similar issue with PlayCanvas, specifically regarding attributes and entity variables? I’d greatly appreciate any insights, tips, or solutions to help me resolve this problem and ensure that my entity variables retain their properties even when navigating between scenes.

Thank you in advance for your assistance!

Best regards

javascriptCopy code

// Example attribute definition
var SetMaterial = pc.createScript('setMaterial');
SetMaterial.attributes.add("setEntity", {type: "entity", title: "set Entity",array: true});

// initialize code called once per entity
SetMaterial.prototype.initialize = function() {
    var _this = this;
    _this.app.on('setMaterial', function (material) {
        _this.setEntity.forEach(function(setEntity){
            let render = setEntity.findComponents('render')[0]
            meshInstances = render.meshInstances;
            if (meshInstances&&meshInstances.length>0) {
                meshInstances[0].material = material.resource
                meshInstances[0].material.update();
            }
        })
        
        }, _this);
    
    
};

Try this code.

// Example attribute definition
var SetMaterial = pc.createScript('setMaterial');
SetMaterial.attributes.add("setEntity", {type: "entity", title: "set Entity",array: true});

// initialize code called once per entity
SetMaterial.prototype.initialize = function() {
    this.app.on('setMaterial', this.setMaterials, this);

    this.on('destroy', function() {
        this.app.off('setMaterial', this.setMaterials, this);
    }, this);
};

SetMaterial.prototype.setMaterials = function(material) {
    this.setEntity.forEach(function(setEntity) {
        let render = setEntity.findComponents('render');
        console.log(render);
        meshInstances = render[0].meshInstances;

        if (meshInstances&&meshInstances.length > 0) {
            meshInstances[0].material = material.resource;
            meshInstances[0].material.update();
        }
    });
};

I don’t know the detail logic. But, If you change the scene, root entity delete at existing scene.

However, events connected to this.app remain linked.
Since it operates in pc.app, it’s essential to turn it off to implement predictable scenarios.

So, you add a code that turns off the event when the entity is destroyed.

1 Like

thank you so much, it works for me! :+1:
sorry for reply so late, It’s been a busy time these days.