- Home /
How to replace materials in the materials array
I try to replace all materials of an object to make the object transparent. No problem there with a single material attached to the object:
cachedObject.renderer.material = inReplaceMat;
If I try to access all materials through the materials[] array though, the material doesn't change.
cachedObject.renderer.materials[0] = inReplaceMat;
Any Ideas? Am I missing something?
The struct, where I try to do this, for better context:
public struct IntersectingObject{
public Material[] cachedMaterial;
public GameObject cachedObject;
public IntersectingObject(GameObject inObj,Material inReplaceMat){
cachedObject = inObj;
cachedMaterial = cachedObject.renderer.materials;
for(int i=0; i<cachedMaterial.Length;i++){
cachedObject.renderer.materials[i] = inReplaceMat;
//cachedObject.renderer.materials[0].SetTexture("_MainTex",cachedMaterial[i].GetTexture("_MainTex"));
}
}
public void restore(){
for(int i=0; i<cachedMaterial.Length;i++){
cachedObject.renderer.materials[i] = cachedMaterial[i];
}
}
}
Answer by Mischa · Jun 05, 2011 at 10:50 AM
After experimenting a lot I finaly found the solution to the problem: renderer.materials gives just a copy of the materials array, not a reference. Changing the materials in it doesn't have any effect on the actual materials of the renderer.
What works is to substitute the whole array at once with a new preconfigured materials array:
intMaterials = new Material[cachedMaterial.Length];
for(int i=0; i<intMaterials.Length;i++){
intMaterials[i] = inReplaceMat;
}
cachedRenderer.materials = intMaterials;
thanks - but can you please elaborate? Not to hijack your question - but I think my query here is the same thing.
This was driving me crazy why it wouldn't update a material when you'd just change one material in the array and your code of recreating the array and then changing one element and re-assigning the materials array works in that the property is now changing. But it's not changing to the right thing. I'm getting a pink empty material.
I'm setting one material in the new array to my newly loaded material but it doesnt work. $$anonymous$$y Resources.Load does seem to correctly load the material (I can debug out its name) - however when I attempt to set the one material in the way you specify here, the material says "None" in the inspector during the game when I assign it.
How can the value of the loaded material be correct in the variable when I Debug.Log it, but appear as "None" when assigned as part of a new materials array like this? Hopefully I am being clear.
$$anonymous$$aybe it's my loaded material? If I load a material, does it's normal map texture get automatically loaded too - or do I have to load that texture too? I thought I only need to load a texure if I want to reassign a texture in a given material, not just choose a different material?? thanks for any thoughts on this...
Have you tried to assign your newly loaded material not to the array, but to the single material property of the renderer? This way you'll see if it's a problem with the array substitution or with the material itself.
If you get a pink rendering you most likely have an empty material in the materials[] array, means something with the recreating of the array or the re-assigning is wrong. Can you post some of your code there?
Thanks $$anonymous$$ischa, just the thing I was looking for :)
Surprising lack of info on this subject! Your answer helped me a lot!
A big thank you for your post, it solved a problem that I had for 2 days and you are the only one that the code really works.
Answer by sisse008 · May 29, 2018 at 08:16 AM
in case this helps anyone, solution for bunch of renderers with each one having bunch of materials.
private Dictionary<Renderer, Material[]> originalMaterials = new Dictionary<Renderer, Material[]>();
void Awake ()
{
//children is a reference to the renderers
children = GetComponentsInChildren<Renderer>();
foreach (Renderer rend in children)
{
//make array of all materials in renderer
Material[] materials = rend.materials;
//add to dictionary renderer and material
originalMaterials[rend] = materials;
}
}
void ChangeToNewMaterial()
{
foreach (Renderer rend in children)
{
var mats = new Material[rend.materials.Length];
for (var j = 0; j < rend.materials.Length; j++)
{
mats[j] = newMaterial;
}
rend.materials = mats;
}
}
void Reset()
{
foreach (KeyValuePair<Renderer, Material[]> pair in originalMaterials)
{
pair.Key.materials = pair.Value;
}
}
in anyone has a better solution please share.
Thankyou
Your answer
Follow this Question
Related Questions
Changing material using an array 1 Answer
Want replace a current object with one inside array the object being replaced with is prefab 1 Answer
Changing a material with a mouse click 2 Answers
Possible to change material as particles are emitted, so each particle has different material? 2 Answers
Spawn object with different material. 0 Answers