Change material properties with a button

ok @yaustar see this code, not working

var Changemoons = pc.createScript('Change Blue Color');

// Reference a list of textures that we can cycle through
Changemoons.attributes.add("textures", {type: "asset", assetType: "texture", array: true, title: "Textures"});

// initialize code called once per entity
Changemoons.prototype.initialize = function() {
   var self = this;
   
   // Keep track of which texture in the array we are currently using
   this.textureIndex = 0;

   // Change textures on button press
 var myMoons = this.app.root.findByName('BlueStars');
   myMoons.element.on('mouseup', this.onMoonsBtnPressed, this);
   };


Changemoons.prototype.onMoonsBtnPressed = function(dt) {
   // Index the next texture in the list, wrapping around if we reach the end
   this.textureIndex = (this.textureIndex + 1) % this.textures.length;

   // Reference the texture
   var texture = this.textures[this.textureIndex].resource;        

   // Go through all the mesh instances of the model and change the diffuse texture on the
   // material to our new one
   var meshInstances = this.entity.model.meshInstances;
   for (var i = 0; i < meshInstances.length; ++i) { 
       var mesh = meshInstances[i];
       mesh.material.diffuseMapTint = new pc.Color(1,0,0);
       mesh.material.update();
   }
};

this is the line 50, can I replace this code? I don’t understand what you suggest me :thinking:

var obj = pc.app.root.findByName('chamferbox');
           if (obj && obj.model && obj.model.model) {
               var material = obj.model.model.meshInstances[0].material;
               if (material) {
                   material.diffuse.set(Math.random(), Math.random(), Math.random());
                   material.update();

I was showing some example code on how to change the diffuse colour on a material so you could apply it to your project.

ok, If I use the same script that I have created to change the diffuse texture and modify some things, it should work for this new objective, right?

Yeah, the code looks pretty close in your last attempt :slight_smile:

Ok @yaustar I hope I can have a good result, I’m excited. All this is to put together a color configurator to paint airplanes, there are many possible combinations and I think the best thing is to have few materials and change their properties. Returning to the script, in my last attempt the code has many references to “texture”, should I replace it with other variables


var ChangeBlueColor = pc.createScript('Change Blue Color');

// initialize code called once per entity
ChangeBlueColor.prototype.initialize = function() {
    var self = this;
    
  

    // Change Diffuse Color on button press
  var myBlueStars = this.app.root.findByName('BlueStars');
    myBlueStars.element.on('mouseup', this.onBlueStarsBtnPressed, this);
    };
 

ChangeBlueColor.prototype.onBlueStarsBtnPressed = function(dt) {
    // Index the next texture in the list, wrapping around if we reach the end
    this.colorIndex = (this.colorIndex + 1) % this.color.length;

    // Reference the Color
    var color = this.color[this.colorIndex].resource;        

    // Go through all the mesh instances of the model and change the diffuse texture on the
    // material to our new one
    var meshInstances = this.entity.model.meshInstances;
    for (var i = 0; i < meshInstances.length; ++i) { 
        var mesh = meshInstances[i];
        material.diffuseMapTint = new pc.Color(1,0,0);
        material.update();
    }
};

this is the error

I do not understand what is wrong on line 17

It is saying the this.color is undefined as you are trying to use the property length from it.

This is where you have to check your code and logic to see why this variable is undefined and whether the code should change to fix the issue.

It is important to understand what the code is currently doing as there’s some here that doesn’t make sense.

For example:

    // Index the next texture in the list, wrapping around if we reach the end
    this.colorIndex = (this.colorIndex + 1) % this.color.length;

    // Reference the Color
    var color = this.color[this.colorIndex].resource;    

color variable is created here but is never used in the rest of the function. Why? What is this code meant to do?

Hello @yaustar Actually these lines were from the original code, I think they should not exist, as it is written down here would be more logical, right?

ChangeBlueColor.prototype.onBlueStarsBtnPressed = function(dt) {
var meshInstances = this.entity.model.meshInstances;
   for (var i = 0; i < meshInstances.length; ++i) { 
       var mesh = meshInstances[i];
       material.diffuseMapTint = new pc.Color(1,0,0);
       material.update();
   }


Yep, that looks good.

material.diffuseMapTint

Are you sure that diffuseMapTint is the material property you want to use? Remember to check the API docs

Ok good @yaustar, I chek this reference, now whith the new code the error is “Material is not defined”

Okay, just to check, do you understand what that error means?

I really do not understand, I see that you are saying that in line 23 is the error, but I can not understand how to fix, I don’t understand how or where I should define the material

When it is saying that blahblah is undefined, it means that variable hasn’t been given a value. It basically doesn’t exist.

In this case, the material variable hasn’t been created yet in this function so we can do:

ChangeBlueColor.prototype.onBlueStarsBtnPressed = function(dt) {
var meshInstances = this.entity.model.meshInstances;
   for (var i = 0; i < meshInstances.length; ++i) { 
       var mesh = meshInstances[i];
       var material; // Created a variable
       material.diffuseMapTint = new pc.Color(1,0,0);
       material.update();
   }
}

But even then, it still has no value, so you will still get the same error. We need to assign it a value and in this case, we want it to reference the meshInstance material.

ChangeBlueColor.prototype.onBlueStarsBtnPressed = function(dt) {
var meshInstances = this.entity.model.meshInstances;
   for (var i = 0; i < meshInstances.length; ++i) { 
       var mesh = meshInstances[i];
       var material = mesh.material; // Now material is referencing the material object from the mesh instance
       material.diffuseMapTint = new pc.Color(1,0,0);
       material.update();
   }
}

Ok, very good explanation. There is no more error, but it does not change color. Is the assigned value (1,0,0) wrong? Or maybe “material.diffuseMapTint” is not correct, as you told me before?

Yep :slight_smile: Have a look through the API docs linked before. You can see that diffuseMapTint doesn’t exist in the API.

Ok @yaustar, is working now. Many thanks I’m happy. te done code

   var meshInstances = this.entity.model.meshInstances;
   for (var i = 0; i < meshInstances.length; ++i) { 
       var mesh = meshInstances[i];
       var material = mesh.material;
       material.diffuse.set(0.2,0.6,0.4);
        material.update();
    }
};

Now I just have to solve the problem of the sub elements of the other post, thanks for helping me I really appreciate it.

1 Like