首先shader graph有个很麻烦的问题就是自定义的keyword始终在面板的最下面不能和普通的属性进行排序,而且也无法展开分组的功能。为了实现通用面板,我们要定义一定的规则
XX面板 溶解面板
XX参数1 溶解参数1
XX参数2 溶解参数2


如果命名中包含面板会特意提出来,如果下面的属性包含XX部分则合并在一个分组中,自定义的keyword始终在最下面的问题,有可以根据命名的规则来进行排序,我会始终让宏在分页的第一位。
上代码:
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
public class CustomShaderGraphGUI: ShaderGUI {
    public class GraphData {
        public string groupName;
        public MaterialProperty title;
        public List < GraphData > child;
    }
    static Dictionary < string,
    GraphData > s_GraphProperty = new Dictionary < string,
    GraphData > ();
    public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) {
        Shader shader = (materialEditor.target as Material).shader;
        s_GraphProperty.Clear();
        for (int i = 0; i < properties.Length; i  ) {
            var propertie = properties[i];
            var displayName = propertie.displayName;
            GraphData data = new GraphData() {
                title = propertie
            };
            if (TryGetGroupName(displayName, out
            var groupName)) {
                if (!s_GraphProperty.TryGetValue(groupName, out
                var graph)) {
                    data.child = new List < GraphData > ();
                    data.groupName = groupName;
                    s_GraphProperty[groupName] = data;
                } else {
                    var attributes = shader.GetPropertyAttributes(i);
                    bool keyword = Array.FindIndex(attributes, (t) = >(t == "Toggle" || t.StartsWith("KeywordEnum"))) >= 0;
                    if (keyword) graph.child.Insert(0, data);
                    else graph.child.Add(data);
                }
            } else {
                s_GraphProperty[displayName] = data;
            }
        }
        PropertiesDefaultGUI(materialEditor);
    }
    private static int s_ControlHash = "EditorTextField".GetHashCode();
    public void PropertiesDefaultGUI(MaterialEditor materialEditor) {
        var f = materialEditor.GetType().GetField("m_InfoMessage", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
        if (f != null) {
            string m_InfoMessage = (string) f.GetValue(materialEditor);
            materialEditor.SetDefaultGUIWidths();
            if (m_InfoMessage != null) {
                EditorGUILayout.HelpBox(m_InfoMessage, MessageType.Info);
            } else {
                GUIUtility.GetControlID(s_ControlHash, FocusType.Passive, new Rect(0f, 0f, 0f, 0f));
            }
        }
        foreach(var props in s_GraphProperty.Values) {
            MaterialProperty prop = props.title;
            if ((prop.flags & (MaterialProperty.PropFlags.HideInInspector | MaterialProperty.PropFlags.PerRendererData)) == MaterialProperty.PropFlags.None) {
                if (props.child != null && props.child.Count > 0) {
                    prop.floatValue = Convert.ToSingle(EditorGUILayout.Foldout(Convert.ToBoolean(prop.floatValue), prop.displayName));
                    if (prop.floatValue == 1f) {
                        foreach(var child in props.child) {
                            DrawGUI(materialEditor, child.title, true);
                        }
                    }
                } else {
                    DrawGUI(materialEditor, prop, false);
                }
            }
        }
        EditorGUILayout.Space();
        EditorGUILayout.Space();
        if (SupportedRenderingFeatures.active.editableMaterialRenderQueue) {
            materialEditor.RenderQueueField();
        }
        materialEditor.EnableInstancingField();
        materialEditor.DoubleSidedGIField();
        materialEditor.EmissionEnabledProperty();
    }
    void DrawGUI(MaterialEditor materialEditor, MaterialProperty prop, bool indentLevel) {
        float propertyHeight = materialEditor.GetPropertyHeight(prop, prop.displayName);
        Rect controlRect = EditorGUILayout.GetControlRect(true, propertyHeight, EditorStyles.layerMaskField);
        if (indentLevel) EditorGUI.indentLevel  ;
        materialEditor.ShaderProperty(controlRect, prop, prop.displayName);
        if (indentLevel) EditorGUI.indentLevel--;
    }
    const string INSPECTOR_TXT = "面板";
    bool TryGetGroupName(string displayName, out string groupName) {
        if (displayName.Contains(INSPECTOR_TXT)) {
            groupName = Regex.Split(displayName, INSPECTOR_TXT, RegexOptions.IgnoreCase)[0];
            return true;
        }
        foreach(var property in s_GraphProperty.Values) {
            if (!string.IsNullOrEmpty(property.groupName)) {
                if (displayName.StartsWith(property.groupName)) {
                    groupName = property.groupName;
                    return true;
                }
            }
        }
        groupName = string.Empty;
        return false;
    }
}
转载声明:本文来源于网络,不作任何商业用途

 









 
 IOS下载
 安卓下载
 小程序