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?

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

C#

ShaderToImport = EditorGUILayout.ObjectField(ShaderToImport, typeof(Shader), true) as Shader;

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, I know it’s really late but for further searchers here is the simplest solution:

ShaderInfo shaders = ShaderUtil.GetAllShaderInfo();

taken from here:

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.