Tween material colour on bespoke 3d object

Hi,

I have the tweening script which works great at changing the material on an object from one colour to the other. But only if it’s a standard 3d object e.g sphere, cube etc…

If I change the asset type to my actual 3d model the script no long works?

var TweenMaterial = pc.createScript('tweenMaterial');

TweenMaterial.attributes.add('fromDiffuse', {type: 'rgb'});
TweenMaterial.attributes.add('toDiffuse', {type: 'rgb'});

TweenMaterial.attributes.add('duration', {type: 'number', default: 1.0});
TweenMaterial.attributes.add('easing', {type: 'string', default: 'Linear'});
TweenMaterial.attributes.add('delay', {type: 'number', default: 0});
TweenMaterial.attributes.add('loop', {type: 'boolean', default: true});
TweenMaterial.attributes.add('yoyo', {type: 'boolean', default: false});
TweenMaterial.attributes.add('repeat', {type: 'number', default: 2});

TweenMaterial.prototype.initialize = function() {
    // have an initial copy of our material
    this.initialMaterial = this.entity.render.material.clone();
        
    // create our tween
    this.reset();
    
    // handle attribute changes
    
    this.on('attr:fromDiffuse', this.reset, this);
    this.on('attr:toDiffuse', this.reset, this);
    
    this.on('attr:duration', function (value) {
        this.tween.duration = value;
    }, this);
    
    this.on('attr:easing', this.reset, this);
    this.on('attr:delay', this.reset, this);    
    this.on('attr:loop', this.reset, this);    
    this.on('attr:yoyo', this.reset, this);    
    this.on('attr:repeat', this.reset, this);
};

TweenMaterial.prototype.reset = function () {                   
    // if we are already tweening then stop first
    if (this.tween) {
        this.tween.stop();
    }
    
    this.tweenedProperties = {
        diffuse: this.fromDiffuse.clone()
    };
    
    // reset our material
    this.entity.render.material = this.initialMaterial.clone();
    this.entity.render.material.diffuse = this.fromDiffuse;
    this.entity.render.material.update();
            
    // create a new tween using our script attributes
    this.tween = this.app.tween(this.tweenedProperties.diffuse)
        .to(this.toDiffuse, this.duration, pc[this.easing])
        .delay(this.delay)
        .loop(this.loop)
        .yoyo(this.yoyo);
    
    // only set repeats if loop is false
    if (! this.loop)
        this.tween.repeat(this.repeat);
    
    
    // update diffuse on each tween update
    this.tween.on('update', function () {      
        this.entity.render.material.diffuse = this.tweenedProperties.diffuse;
        this.entity.render.material.update();
    }.bind(this));
    
    // start the tween
    this.tween.start();
};

Hi @Mattturner2021,

If you are using a custom asset as model you need to follow a different direction to grab the material/materials that you need.

Instead of using this:

const material = this.entity.render.material;

To get the material of the first mesh instance of your asset, you need to do this:

const material = this.entity.render.meshInstances[0].material;
1 Like

nice one works :slight_smile:

1 Like