Change color to multiple Materials in one gameObject?

Hello guys. I’m trying to change the color for all materials on my gameObject, but it only change the first one…

I’m using this code:

gameObject.renderer.material.color = Color.red;

but the gameObject i want to change the color, have tons of materials :frowning:
is there a way to change the colors to all materials easily?

It says it need an ")" after mat, why? :(

–

Thanks! But how do i make it return to the original color? i tried for (var i = 0; i < renderer.materials.length; i++) { renderer.materials*.color = Color.red;* } yield WaitForSeconds (0.6); renderer.materials*.color = Color.white;* but it gives me IndexOutOfRange... Actually, it would be better if i could return to the color before the red, because not every material is white. Ty ^^

–

Your yield and second materials assignment statement are not contained in the for loop currently - move the closing curly bracket to the end of that snippet. To return to the original material, you'll have to create a material[] array and populate it with the starting materials, then loop through the array and reassign them.

–

3 Answers

3

use renderer.materials instead of renderer.material:

C#:

foreach (Material mat in renderer.materials) {
    mat.color = Color.red;
}

Javascript:

for (var i = 0; i < renderer.materials.length; i++) {
    renderer.materials*.color = Color.red;*

}
If you want to return the original colors, you have to first change ALL the colors, then yield, then after returning change back ALL the colors. You can’t yield between changing one material and changing it back…
for (var i = 0; i < renderer.materials.length; i++) {
renderer.materials*.color = Color.red;*
}
yield WaitForSeconds(0.6);
for (var i = 0; i < renderer.materials.length; i++) {
renderer.materials*.color = Color.white;*
}

Unfortunately, materials doesn’t have a .color method, as .color addresses the main material on an object, while materials returns the full array of materials on an object. If you’d like to modify the color of all materials on an object, better to cache the original materials, then modify the array inside of a for loop.

oldMaterials : Material[] = renderer.materials;

    for (var i = 0; i < renderer.materials.length; i++) {
        renderer.materials*.color = Color.red;*

}
Then, once you’ve completed any other operation you’d like, just restore your old material array:
renderer.materials = oldMaterials;

I got it now, the problem is, that, when i change the color to red, it also change the colors to red on oldMaterials... why?? another strange thing, is when i store the children materials into oldMaterials, it automaticaly changes the materials for my children gameObject! it changes to "nameofmaterial(Instance)", the same one that gets stored into oldMaterials, why? :(

–

And how can i store an array of colors from the children materials? i tried a few things here, but none work... and after that, how can i go back to it?

–

You can also use material Property blocks which are faster than creating materials at runtime.

Declare a MPB and init it later use it in a for loop. In 2018 you can give it a material index when setting the meshrenderer MPB which in this case it’s “i”.

MaterialPropertyBlock MPB;

void ChangeMaterials()
{
MPB = new MaterialPropertyBlock();

for(i = 0; i < meshRenderer.materials.coun; i++)
{
MPB.SetColor(Color.Red)

meshRenderer.SetPropertyBlock(MPB, i);
}
}