From that example, I know how to change the diffuse colour in the box from a HTML button (HTML/CSS UI | Learn PlayCanvas).
Please tell me how to change the material from one to the other triggering it also from a HTML button. Is that possible?
Sometimes there are a lot of settings changed and It would be much faster to me switch material than to change every single attribute.
I would like to apply to change material to every subobject from a hierarchy tree (So I have a locator as a parent and a few objects under it. I would like to change the material on every child mesh of the parent locator.
You should be able to change the material of an object through an HTML button. To switch materials in runtime through scripts, take a look at this example. As for how to trigger that with an HTML button, there is also this example, which is incredibly close to what you’re trying to achieve.
Thanks for helping me and sorry that I`ve not shared enough info.
console.log proves that I`ve already changed ‘oldMaterial’ to ‘newMaterial’ (as I wanted to do) but nothing happens in the viewer (I still see oldMaterial - red one);
I would like to toggle on/off between two materials ‘oldMaterial’ and ‘newMaterial’;
The reason that the button doesn’t appear to be working is that your script currently only updates the name of the material in question. In order to update the actual material, you will want to change the actual object attached to the meshInstance in question. I slightly modified your script to now change the actual material object on the box like this:
var Ui = pc.createScript('ui');
Ui.attributes.add('css', {type: 'asset', assetType:'css', title: 'CSS Asset'});
Ui.attributes.add('html', {type: 'asset', assetType:'html', title: 'HTML Asset'});
Ui.prototype.initialize = function () {
// create STYLE element
var style = document.createElement('style');
// append to head
document.head.appendChild(style);
style.innerHTML = this.css.resource || '';
// Add the HTML
this.div = document.createElement('div');
this.div.classList.add('container');
this.div.innerHTML = this.html.resource || '';
// append to body
// can be appended somewhere else
// it is recommended to have some container element
// to prevent iOS problems of overfloating elements off the screen
document.body.appendChild(this.div);
this.counter = 0;
this.bindEvents();
};
Ui.prototype.bindEvents = function() {
var self = this;
// example
//
// get button element by class
var button = this.div.querySelector('.button');
var counter = this.div.querySelector('.counter');
// if found
if (button) {
// add event listener on `click`
button.addEventListener('click', function() {
++self.counter;
if (counter)
counter.textContent = self.counter;
console.log('button clicked');
// try to find object and change its material diffuse color
// just for fun purposes
var obj = pc.app.root.findByName('box');
if (obj && obj.render) {
var material = obj.render.meshInstances[0].material;
if (material) {
// console.log(material.name)
//material.name.set('newMaterial');
// material.name = 'newMaterial';
// material.update();
obj.render.meshInstances[0].material = self.app.assets.find('newMaterial', 'material').resource;
}
}
}, false);
}
if (counter)
counter.textContent = self.counter;
};
The change that I made is rather quick and dirty (look at line 57), and you would likely want to find a better way of getting your materials other than searching by name for them in the future, but for now, this should work for you.
You may want to take sometime to review this section of the user manual to get better aquainted with the way materials work in Playcanvas: