I’m trying to basically store all of the materials paths that use a specific shader, in this case: test/oldshader, into a list of string type. Then we remove test/oldshader and import a new shader called test/newshader… I then want to apply the Material that was using test/oldshader, which is now an Hidden/InternalErrorShader, but i dont want to check for InternalErrorShader because there might be other InternalErrorShaders in the project that it hasnothing to do with. This method is supposed to just change the oldshaders to the newshaders, not touching anything else really. :).
Anyways, the problem I think im having is that the UnityEditor is not updating and therefore thinks that it doesn’t have a “test/newshader” so it either sets an Hidden/InternalErrorShader as the shader for the material or just doesnt do anything. How can I fix this issue. I want to just apply it after importing of the asset of test/newshader. I have my entire method below with placeholders to cut out “unimportant” details.
Any help is appreciated.
Thanks.
string[] guids = AssetDatabase.FindAssets("t: material");
List<string> mats2Fix = new List<string>();
foreach (string guid in guids)
{
string p = AssetDatabase.GUIDToAssetPath(guid);
Material temp = (Material)AssetDatabase.LoadAssetAtPath(p, typeof(Material));
if (temp != null && temp.shader.name.ToLower().Contains("test/oldshader")) mats2Fix.Add(AssetDatabase.GetAssetPath(temp.GetInstanceID()));
}
// Place Holder for Removing test/oldshader
// Place Holder for Importing test/newshader.unitypackage with test/newshader, which is the new shader I want to apply to the materials that were using test/oldshader
foreach (string mat2Fix in mats2Fix)
{
if (File.Exists(Application.dataPath + mat2Fix.Substring(6))) // Substring because Application.dataPath already contains "Assets", which is also in mat2Fix... so substring it but we need it later for loading.
{
Material temp = (Material)AssetDatabase.LoadAssetAtPath(mat2Fix, typeof(Material));
temp.shader = Shader.Find("test/newshader");
}
}
AssetDatabase.SaveAssets();
I just now attempted to change the materials shader to just the regular old Standard shader, which worked flawlessly. So I believe that my idea of why it’s not setting it to test/newshader is correct, its that the unityeditor is not finding it since the importing takes place shortly before and doesn’t have enough time to actually update the frame or something. I’d also like to point out that using the same method, with just the changing of shader part of the script, it flawlessly changes it to test/newshader without any problems. This only occurs when I import the package and shader through the script THEN attempt to apply the shader to the material. So, that’s why I think that it’s the UnityEditor just not being refreshed… However, I’m not sure where to go from here. I’m completely lost as to what I can do now about this… If you or anyone can guide me in the right direction, I would be much appreciated.
It sounds like this is probably the issue: I’ve had issues with this name search before, but it was years ago. I just put Shader.Find() into the same camp of “functions that the compiler cannot help you with” and avoid it.
I know this is only an editor script, but this method also has runtime issues because unless that shader is referenced by at least one material in your built game, it will silently get asset-stripped and fail to be found. Unity does NOT include all shaders, only what is apparently used.
Are there any alternatives? Maybe finding the asset for the shader itself and applying it manually? but then again, I don’t know how I would achieve this.