After switching levels and then switching back, the activetargets attribute under morphinstance will lose data

I don’t know if this is a bug. Our playcanvas project needs to switch levels dynamically. When we call MorphTarget in a level and control its changes through scripts, the first load is normal. After switching levels back, Morph control via script becomes no longer available.

After outputting from the console, I found that the ActiveTargets array became empty before and after the switch. Is this a bug? Or something else? How to solve it?

Projectg Link: PlayCanvas 3D HTML5 Game Engine

you should control morph targets using functionality on MorphInstance, and not using internal undocumented arrays. This should work well: https://developer.playcanvas.com/en/api/pc.MorphInstance.html

1 Like

check out the example source code here:
http://playcanvas.github.io/#graphics/mesh-morph.html

note that this creates morph targets as well … you probably don’t need that part as you likely load them as glb?

You may have misunderstood what I mean, I did use MorphInstance to control Morph animation, but after switching the level, this control is invalid.

var ControlMorph = pc.createScript('controlMorph');

ControlMorph.attributes.add('speed',{type: 'number', default: 0.5});
ControlMorph.attributes.add('loop', {type: 'boolean', default: false});

// initialize code called once per entity
ControlMorph.prototype.initialize = function() {
    
    this.timer = 0;    
    var morphInstance = this.entity.model.meshInstances[0].morphInstance;

    morphInstance.setWeight(0, 1);
    morphInstance.setWeight(1, 0);
    
    this.on('destroy', function(){
        this.timer = 0;
        morphInstance.setWeight(0, 1);
        morphInstance.setWeight(1, 0);
    });
    
};

ControlMorph.prototype.update = function(dt) {
        
    this.timer += dt;
    if (!this.loop){
        this.timer = Math.min(1 / this.speed - 0.01, this.timer);
    }

    var morphInstance = this.entity.model.meshInstances[0].morphInstance;

    morphInstance.setWeight(0, 1 - this.timer * this.speed % 1);
    morphInstance.setWeight(1, this.timer * this.speed % 1);
    
};

ControlMorph.prototype.onPlaying = function(){
    
    this.timer = 0;
    var morphInstance = this.entity.model.meshInstances[0].morphInstance;
    morphInstance.setWeight(0, 1);
    morphInstance.setWeight(1, 0);
    console.log(morphInstance);
    
};

So I think this is a bug :no_mouth:

You can try my picture-based solution. I think the problem is that the target data is destroyed when the destroy event is called, and the data is empty when it is loaded again.

2 Likes

Can solve the problem! Thank you so much