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

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 *.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 .sharedMaterials = tempMats ;

* }*
* }*
}

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 :slight_smile: