- Home /
How do I apply Default-Diffuse material to a MeshRenderer in code?
As part of a custom mesh script, in edit mode, I have a menu item that creates an empty game object to host the custom mesh component as well as adds a MeshFilter and a MeshRenderer.
GameObject go = new GameObject();
go.name = "Expandable Plane";
go.AddComponent("MeshFilter");
go.AddComponent("MeshRenderer");
However, the MeshRenderer has no materials or sharedMaterials set on it. When I manually create primitives like cubes or spheres, the MeshRenderer automatically has the Default-Diffuse material applied. I'd like to apply this to my MeshRenderer, but am struggling to actually find the material using an Editor script.
GameObject.Find("Default-Diffuse");
Turns up null, so does:
Shader.Find("Default-Diffuse");
I know there's a "Diffuse" shader that I could make a new material instance of, but I want to use the Default-Diffuse material as a sharedMaterial to avoid leaks.
Answer by Soviut · Jan 30, 2013 at 11:40 PM
My current hack solution is to temporarily create another primitive (plane, cube, whatever) and get the Default-Diffuse material from its sharedMaterial and apply it to my new object.
GameObject primitive = GameObject.CreatePrimitive(PrimitiveType.Plane);
primitive.active = false;
Material diffuse = primitive.GetComponent<MeshRenderer>().sharedMaterial;
DestroyImmediate(primitive);
// ...
go.renderer.sharedMaterial = diffuse;
Answer by sirbrialliance · Sep 02, 2013 at 08:03 PM
Here's a simple snippet:
//set the default material
MeshRenderer mr = go.GetComponent<MeshRenderer>();
mr.material = new Material(Shader.Find("Diffuse"));
Answer by numberkruncher · Feb 17, 2015 at 03:07 AM
The following undocumented function seems to work in editor scripts:
var mat = AssetDatabase.GetBuiltinExtraResource<Material>("Default-Diffuse.mat");
Sadly relies on Unity.Editor
(thus can't be used in a build). EDIT: Which OP doesn't care but others readers might. Workaround solution: Set it on Reset
:)
[+1] - This is just what I need, it's great for assigning run-time debug object in the scene. Thanks :D
Answer by Acegikmo · Oct 23, 2014 at 12:12 PM
Late answer, but, here's a way of getting it without creating a default primitive :)
// using System.Reflection;
// using UnityEditor;
MethodInfo getBuiltinExtraResourcesMethod;
Material GetDefaultMaterial() {
if( getBuiltinExtraResourcesMethod == null ) {
BindingFlags bfs = BindingFlags.NonPublic | BindingFlags.Static;
getBuiltinExtraResourcesMethod = typeof( EditorGUIUtility ).GetMethod( "GetBuiltinExtraResource", bfs );
}
return (Material)getBuiltinExtraResourcesMethod.Invoke( null, new object[] { typeof( Material ), "Default-Diffuse.mat" } );
}
Answer by Berenger · Jan 30, 2013 at 12:17 PM
Try that :
Material diffuse = new Material
(
"Shader \"Tutorial/Basic\" {\n"
+" Properties {\n"
+" _Color (\"Main Color\", Color) = (1,1,1,1)\n"
+" }\n"
+" SubShader {\n"
+" Pass {\n"
+" Material {\n"
+" Diffuse [_Color]\n"
+" }\n"
+" Lighting On\n"
+" }\n"
+" }\n"
+"}"
);
renderer.sharedMaterial = diffuse;
More infos : http://docs.unity3d.com/Documentation/ScriptReference/Material.Material.html
I'm not interested in creating a new shader or material, I just want to find and use the Default-Diffuse material that can be found in the Assets list in the material picker.
I can manually use choose the Default-Diffuse shader in the editor, it would make sense that I could do the same through code.
You could use a GameObject that specifically hold that material. Create a script with a public $$anonymous$$aterial, affect it on a GameObject and set the default diffuse mat. Then, anywhere in your codes, you can find that GameObject, get the component and access the material.
A clean way would be better obviously, but that's all I got :/
Unity is very efficient and when building only exports the materials that are used in a scene. So you need to add a $$anonymous$$aterial variable somewhere in code to a script, or just attached to a gameobject like the comment above. I personaly create an script class that just holds various materials that need to be dynamically changed during the game. If you had alot of materials (and textures in those materials) this method could be wasteful during runtime.