- Home /
Select Shader in Custom Editor GUI
I would like to have a shader selection drop-down (similar to that found in the material inspector) to allow users to select the shader that they would like to use with batch-generated materials.
selectedShader = ???.ShaderField(selectedShader);
If there is no way to reuse the material inspector field, how can this be reproduced?
Answer by Acegikmo · Sep 25, 2013 at 09:46 PM
I finally managed to figure out a definitive solution, which works for me, running Unity 4.2:
MenuCommand mc;
private void DisplayShaderContext(Rect r) {
if( mc == null )
mc = new MenuCommand( this, 0 );
// Create dummy material to make it not highlight any shaders inside:
string tmpStr = "Shader \"Hidden/tmp_shdr\"{SubShader{Pass{}}}";
Material temp = new Material( tmpStr );
// Rebuild shader menu:
UnityEditorInternal.InternalEditorUtility.SetupShaderMenu( temp );
// Destroy temporary shader and material:
DestroyImmediate( temp.shader, true );
DestroyImmediate( temp, true );
// Display shader popup:
EditorUtility.DisplayPopupMenu( r, "CONTEXT/ShaderPopup", mc );
}
private void OnSelectedShaderPopup( string command, Shader shader ) {
if( shader != null ) {
Debug.Log("Clicked shader: " + shader.name);
}
}
The other methods didn't work for me, they didn't show all shaders, but this one did :)
Thanks, works great. I struggled a bit to understand how to use it, but it simply works by calling something like :
if (GUILayout.Button("Change shader"))
{
DisplayShaderContext(GUILayoutUtility.GetRect(GUIContent.none,EditorStyles.popup));
}
I'm not sure I understand how unity end up calling OnSelectedShaderPopup, but it gets called on picking from the list all right.
Well, Unity probably uses Send$$anonymous$$essage / Reflection like most the time. It's quite inefficient to create and destroy a material (and shader) each call. It's better to create it in OnEnable and destroy it in OnDisable.
@khan-amil: OnSelectedShaderPopup is a callback method to the object passed to $$anonymous$$enuCommand: mc = new $$anonymous$$enuCommand(myEditorClass, 0);
Answer by ScroodgeM · Aug 26, 2012 at 07:08 PM
C#
ShaderToImport = EditorGUILayout.ObjectField(ShaderToImport, typeof(Shader), true) as Shader;
Nice idea, though unfortunately this doesn't allow one to select from the built-in shaders. Do you know if there is a way to get a list of all available shaders? Perhaps such a list could be used to produce a similar but custom control. Thanks
Answer by numberkruncher · Sep 05, 2012 at 02:48 AM
I think that I have finally found my answer:
// Create and cache a dummy material
if (_dummyMaterial == null) {
_dummyMaterial = new Material(Shader.Find("Diffuse"));
_dummyMaterial.hideFlags = HideFlags.HideAndDontSave;
}
// First ensure that all shader assets are loaded
UnityEditorInternal.InternalEditorUtility.SetupShaderMenu(_dummyMaterial);
// Fetch all shader assets
Shader[] shaders = (Shader[])UnityEngine.Resources.FindObjectsOfTypeAll(typeof(Shader));
// Filter out those that are supposed to be hidden
shaders = shaders.Where(s => s != null && s.name != "" && !s.name.StartsWith("__")).ToArray();
This appears to be a better solution than my previous one because it works without having previously selected the shader popup menu for a material. Not perfect, but as good as I could figure out.
Hi Lea, how did you feed the Shader[] to your custom editor UI to show the selection drop down?
@Ian I have put an example together for you: http://pastebin.com/bbDhu0NX
this does not work anymore in Unity 4.2.1. It only lists a couple of the standard shaders but not all of them. Any ideas why and how to solve it?
Answer by Cobo3 · Feb 10, 2016 at 05:39 PM
Maybe you would like to have a look at String-O-Matic. You can have a nice list of available shaders as a dropdown in the inspector. You would still need to call Shader.Find, but at least you know the shader in question exists.
Your answer

Follow this Question
Related Questions
How To Open GUI Editor? 1 Answer
Why are all my GUITexture elements semi-transparent? 0 Answers
Trigger an event from editor script? 0 Answers
Custom Material Editor 1 Answer
Why changing material shader at runtime also affect my asset on disk? 3 Answers