- Home /
How does assigning materials to MeshRenderer.sharedMaterials work?
I am procedurally generating a cube mesh in the editor. Each of its faces can be enabled or disabled. Each enabled face is created as a separate submesh and materials are assigned to MeshRenderer.sharedMaterials accordingly. However, in MeshRenderer's inspector, materials does not reflect that assignment, whatever I manually assign does not change. This is the code I use:
void updateMaterials(int meshcount) {
if (meshrenderer.sharedMaterials.Length != meshcount) {
meshrenderer.sharedMaterials = new Material[meshcount];
}
int j = 0;
for (int i = 0; i < faces.Length; i++) { // faces: bool[6], true when face exists
if (faces[i]) {
meshrenderer.sharedMaterials[j] = materials[i];
Debug.Log(j.ToString() + ": " + materials[i].ToString());
// Output:
// 0: Floor (UnityEngine.Material)
// 1: Wall-bricks (UnityEngine.Material)
j++;
}
}
}
Does anybody know what I am doing wrong here? Thanks.
I think you need to reverse order of assignment. First fill up a new array with the materials you need. Then override shared$$anonymous$$aterials with it. In your case, whenever you are assigning to an index of shared$$anonymous$$aterials, you're assigning to a returned copy, probably.
Answer by maccabbe · Mar 09, 2015 at 05:23 PM
The reason this is not changing is because renderer.materials and renderer.sharedMaterials return a copy of the materials, even when assigning. That means the following line
meshrenderer.sharedMaterials[j] = materials[i];
is the same as
Material[]sharedMaterials=meshrenderer.sharedMaterials;
sharedMaterials[j] = materials[i];
so you never assign the materials back to the renderer. You want to use something like the following
void updateMaterials(int meshcount)
if(meshrenderer.sharedMaterials.Length!=meshcount) {
meshrenderer.sharedMaterials=new Material[meshcount];
}
Material[] sharedMaterials=meshrenderer.sharedMaterials;
int j=0;
for(int i=0; i<faces.Length; i++) { // faces: bool[6], true when face exists
if(faces[i]) {
sharedMaterials[j]=materials[i];
Debug.Log(j.ToString()+": "+materials[i].ToString());
// Output:
// 0: Floor (UnityEngine.Material)
// 1: Wall-bricks (UnityEngine.Material)
j++;
}
}
meshrenderer.sharedMaterials=materials;
}
http://docs.unity3d.com/ScriptReference/Renderer-sharedMaterials.html
Your answer
Follow this Question
Related Questions
How to check whether a lot of components and their children have a mesh renderer on them in code? 1 Answer
OBJ model can only have instance materials? 1 Answer
Add mesh with materials to scene through code. 0 Answers
How do I properly apply a transparent texture to a mesh? 2 Answers
Materials on an imported mesh 1 Answer