- Home /
Finding and replacing all "instanced" materials
In my efforts to write an editor script which replaces shaders on all scene objects, I made the mistake of using:
transform.renderer.material.shader = newShader;
instead of:
transform.renderer.sharedMaterial.shader = newShader;
Since the editor script is set to [ExecuteInEditMode], when ran, it created "instances" off all materials. Now I have to go through all my objects and reset their material to the default one, since they all have an "instance" material now.
Is there a way to find and loop through all material "instances" and reset them to the default, non-instanced material?
Stephane
Answer by sumittyagi · Mar 10, 2018 at 11:29 AM
Hi, May be its too late , but i would like to share it for others who have done such a simple mistake like me,
Using this you can revert back to your original materials, without doing it manually and later remove this script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class RevertOriginalMaterials : MonoBehaviour {
Renderer[] All_Objects;
void Awake()
{
All_Objects = GetComponentsInChildren<Renderer> ();
}
void Start(){
for (int i = 0; i < All_Objects.Length; i++)
{
Material[] originalMats = Resources.FindObjectsOfTypeAll<Material>();
Material[] mats = All_Objects [i].sharedMaterials;
Material[] tempMats = new Material[mats.Length];
for (int j = 0; j < originalMats.Length; j++) {
for (int k = 0; k < mats.Length; k++) {
if (originalMats [j].name + " (Instance) (Instance)" == mats [k].name) {
tempMats [k] = originalMats [j];
}
else if(originalMats [j].name + " (Instance)" == mats[k].name)
{
tempMats [k] = originalMats [j];
}
else if (originalMats [j].name == mats [k].name) {
tempMats [k] = originalMats [j];
}
}
}
All_Objects [i].sharedMaterials = tempMats ;
}
}
}
Life saver! I screwed as the OP XD. I had even multiple materialname(instance) (instance) it took a while for the loops to finish in a 5$$anonymous$$+renderers scene . TX!!
Answer by fherbst · Mar 17, 2012 at 11:15 PM
With another editor script? As far as I can remember, when Unity instantiates something, it appends "(Clone)" to the name... maybe you could go through all scene materials, check the name, and set the original one. You can probably get the material you need via AssetDatabase.LoadAllAssetsAtPath (searching for the right material asset recursively). Lots of work for a simple mistake :-)
It's different for materials when you use "renderer.material" ins$$anonymous$$d of "renderer.shared$$anonymous$$aterial", as using the first example creates an "instance" of the material at runtime, so it doesn't actually exist in the project folder, and it shows up as "material name (instance)" in the editor window.
Your answer
Follow this Question
Related Questions
Material doesn't have a color property '_Color' 4 Answers
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
how do i create material instances without errors 4 Answers
SetMaterialBlock - anyone use this or know where documentation is? 2 Answers
Why does reading MeshRenderer.material change MeshRenderer.sharedMaterial? 1 Answer