- Home /
Is there a way to change the shader on all meshes without doing it manually one by one?
I have dozens of meshes textured off of photograph-based UV sets. My team has created a self-illumination shader that allows the textures to produce the game lighting (Example - An office building texture with a self-illum shader mirrors the lighting from the photograph.)
When I import the meshes in Unity from Maya 2010, it defaults all shaders to diffuse.
Is there a way to replace all of the shaders assigned to all of the meshes in a batch like process; Or, can a default shader be declared in the project that forces Unity to use self-illumination as the default?
Any ideas or resource guidance on this issue will be helpful. Thanks!
Answer by Eric5h5 · Apr 05, 2010 at 07:52 PM
Use this editor script on the wiki to mass-assign materials.
I just added a post down below with a link to an editor extension on the Asset Store that actually does this stuff. I'll add it in here as well in case anyone wanders through here - Legacy 2 PBR
Answer by cregox · Nov 23, 2011 at 08:32 PM
Since we can't easily list all shaders, using a TextField is the best I've got, after modifing the script from wiki:
using System;
using UnityEditor;
using UnityEngine;
class MassMaterialEditor : EditorWindow
{
static MassMaterialEditor window;
String oldShaderName;
Color oldMainColor;
Color oldSpecColor;
float oldShininess;
Texture2D oldLightmap;
[MenuItem("Character Generator/Mass Material Editor")]
static void Execute()
{
if (window == null)
window = (MassMaterialEditor)GetWindow(typeof (MassMaterialEditor));
window.Show();
}
void OnGUI()
{
Shader shader = Shader.Find(EditorGUILayout.TextField("Shader", oldShaderName));
if (shader != null) if (shader.name != oldShaderName)
{
oldShaderName = shader.name;
SetProperty("_Shader", shader);
}
EditorGUILayout.Separator();
GUILayout.Label("--- Render Settings ---");
RenderSettings.fog = EditorGUILayout.Toggle("Fog", RenderSettings.fog);
RenderSettings.fogColor = EditorGUILayout.ColorField("Fog Color", RenderSettings.fogColor, GUILayout.Width(140));
RenderSettings.fogDensity = EditorGUILayout.Slider("Fog Density", RenderSettings.fogDensity, 0, 1);
RenderSettings.ambientLight = EditorGUILayout.ColorField("Ambient", RenderSettings.ambientLight, GUILayout.Width(140));
EditorGUILayout.Separator();
GUILayout.Label("--- Material Settings ---");
GUILayout.Label("Selected Materials are modified");
Color mainColor = EditorGUILayout.ColorField("Main Color", oldMainColor, GUILayout.Width(140));
if (mainColor != oldMainColor)
{
oldMainColor = mainColor;
SetProperty("_Color", mainColor);
}
Color specColor = EditorGUILayout.ColorField("Spec Color", oldSpecColor, GUILayout.Width(140));
if (specColor != oldSpecColor)
{
oldSpecColor = specColor;
SetProperty("_SpecColor", specColor);
}
float shininess = EditorGUILayout.Slider("Shininess", oldShininess, .01f, 1, GUILayout.Width(250));
if (shininess != oldShininess)
{
oldShininess = shininess;
SetProperty("_Shininess", shininess);
}
Texture2D lightmap = (Texture2D)EditorGUILayout.ObjectField("Lightmap", oldLightmap, typeof(Texture2D));
if (lightmap != oldLightmap)
{
oldLightmap = lightmap;
SetProperty("_LightMap", lightmap);
}
}
static void SetProperty(string prop, object value)
{
foreach (Material m in Selection.GetFiltered(typeof(Material), SelectionMode.DeepAssets))
{
if (value is Shader)
{
m.shader = (Shader)value;
continue;
}
if (!m.HasProperty(prop)) continue;
if (value is float)
{
m.SetFloat(prop, (float)value);
continue;
}
if (value is Color)
{
m.SetColor(prop, (Color)value);
continue;
}
if (value is Texture)
{
m.SetTexture(prop, (Texture)value);
continue;
}
throw new Exception("Unexpected type for " + prop + ": " + value.GetType());
}
}
}
Answer by qJake · Apr 05, 2010 at 05:11 PM
Well... for starters, I'm sure you could write an Editor script to do it for you. Here's the class overview for Editor scripts:
http://unity3d.com/support/documentation/ScriptReference/20_class_hierarchy.Editor_Classes.html
Unfortunately, Unity doesn't support multi-select editing (yet), so if you can't find a solution, you may just have to suck it up, throw on some music, and do it manually.
You could also try exporting some other way from Maya... instead of using the Maya format, you could try .FBX (or the other way around). Unity may import the materials differently using different file formats.
@SpikeX: Unity doesn't import $$anonymous$$aya files, it opens $$anonymous$$aya in the background and makes it export to .FBX. So there is no difference. Anyway Unity doesn't import materials from 3D apps at all, because there's no real way to convert them.
One of the few types of model files it doesn't import then... strange. :P