估计需要自定义Shader 的人不多
下面内容就看看
作为小白的我们,无从入手,当然首先看看 Amplify Shader Editor(ASE)是如何实现Shader定义,
从(ASE)的Shader代码,得知自定义原理(代码)
//CustomEditor "ASEMaterialInspector"
CustomEditor "SkinShaderGUI_URP_SRP"
Fallback "Hidden/InternalErrorShader"
}
public override void OnGUI( MaterialEditor materialEditor, MaterialProperty[] properties )
{
IOUtils.Init();//IOUtils还不算特别
Material mat = materialEditor.target as Material;
//。。。zheli这里又一堆特别代码
//。。。
Shader shader = mat.shader;
int propertyCount = UnityEditor.ShaderUtil.GetPropertyCount( shader );
for( int i = 0; i < properties.Length; i++ )
{
if( ( properties[ i ].flags & ( MaterialProperty.PropFlags.HideInInspector | MaterialProperty.PropFlags.PerRendererData ) ) == MaterialProperty.PropFlags.None )
{
// Removed no scale offset one line texture property for consistency :( sad face
//if( ( properties[ i ].flags & MaterialProperty.PropFlags.NoScaleOffset ) == MaterialProperty.PropFlags.NoScaleOffset )
//{
// object obj = MaterialPropertyHandlerEx.GetHandler( mat.shader, properties[ i ].name );
// if( obj != null )
// {
// float height = MaterialPropertyHandlerEx.GetPropertyHeight( obj, properties[ i ], properties[ i ].displayName, materialEditor );
// //Rect rect = (Rect)materialEditor.GetType().InvokeMember( "GetPropertyRect", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, materialEditor, new object[] { properties[ i ], properties[ i ].displayName, true } );
// Rect rect = EditorGUILayout.GetControlRect( true, height, EditorStyles.layerMaskField );
// MaterialPropertyHandlerEx.OnGUI( obj, ref rect, properties[ i ], new GUIContent( properties[ i ].displayName ), materialEditor );
// if( MaterialPropertyHandlerEx.PropertyDrawer( obj ) != null )
// continue;
// rect = EditorGUILayout.GetControlRect( true, height, EditorStyles.layerMaskField );
// materialEditor.TexturePropertyMiniThumbnail( rect, properties[ i ], properties[ i ].displayName, string.Empty );
// }
// else
// {
// materialEditor.TexturePropertySingleLine( new GUIContent( properties[ i ].displayName ), properties[ i ] );
// }
//}
//else
//{
float propertyHeight = materialEditor.GetPropertyHeight( properties[ i ], properties[ i ].displayName );
Rect controlRect = EditorGUILayout.GetControlRect( true, propertyHeight, EditorStyles.layerMaskField, new GUILayoutOption[ 0 ] );
materialEditor.ShaderProperty( controlRect, properties[ i ], properties[ i ].displayName );
//}
}
}
}
官方的 materialEditor 给我们准备了所有API,只要调用 materialEditor.ShaderProperty 即可
自定义Shader步骤:
(你需要又一点点Unity经验,和Editor的Window或者Inspector经验即可)
基础自定义步骤
创建一个类,继承ShaderGUI
重写OnGUI( MaterialEditor materialEditor, MaterialProperty[] properties )
获取 Material mat = materialEditor.target as Material;
获取mat.shader的属性
用materialEditor.ShaderProperty显示该方法
普通属性上半部分
void OnProptyCommonGUI(string key)
{
var specFloat = FindProperty(key, _properties);//先不管这个错误处理了。。。
_materialEditor.ShaderProperty(specFloat, new GUIContent(specFloat.displayName, ""));
}
这样我们就完成了属性部分
没了??就这??
EditorGUILayout.Space();
materialEditor.RenderQueueField();
materialEditor.EnableInstancingField();
materialEditor.DoubleSidedGIField();
materialEditor.LightmapEmissionProperty();
再完成下半部分,
如果你想隐藏,则不需要了。。。
浅浅的自定义一个折叠Group
//关键在于代码新开始一个Button 样式: Rect r_texturecolor = EditorGUILayout.BeginVertical("Button");
_properties = properties;
_materialEditor = materialEditor;
//OnSpecularGUI(materialEditor,properties);
OnSpecularFoldOutGUI();
void OnSpecularFoldOutGUI()
{
Rect r_texturecolor = EditorGUILayout.BeginVertical("Button");
//Rect r_outline = EditorGUILayout.BeginVertical("Button");
showSpecular = EditorGUILayout.Foldout(showSpecular, "(Specular - )", true, EditorStyles.foldout);
if (showSpecular)
{
OnProptyCommonGUI("_SpecularMapm");
OnProptyCommonGUI("_Specular");
}
EditorGUILayout.EndVertical();
}
void OnProptyCommonGUI(string key)
{
var specFloat = FindProperty(key, _properties);//先不管这个错误处理了。。。
_materialEditor.ShaderProperty(specFloat, new GUIContent(specFloat.displayName, ""));
}
总结:
多说无益,Show me the Code