Zephus 发表于 2022-2-24 11:17

Unity-Shading-ShaderGUI

需求:
ShaderGUI这东西不赘述了,美术需求 没有的话就像下图这样 变量一多就懵了,尤其是新进到项目组的美术,知乎上的写法也很多



无GUI

代码:
绘制模块脚本
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

public static class XXVFXGUIHelper
{
    static private GUIStyle _BigHeaderLabel;
    static public bool DissError;
      static public GUIStyle BigHeaderLabel
    {
      get
      {
            _BigHeaderLabel = new GUIStyle(EditorStyles.largeLabel);
            _BigHeaderLabel.fontStyle = FontStyle.Bold;
            _BigHeaderLabel.fontSize = 14;
            _BigHeaderLabel.alignment = TextAnchor.MiddleLeft;
            _BigHeaderLabel.fixedHeight = 30;

            Color[] pix = new Color;

            if (DissError == true)
            {
                pix = Color.red*(Mathf.Sin(Time.time*10)); //自定义的报错显示
            }
            else
            {
                pix = Color.gray;
            }
               
            Texture2D result = new Texture2D(1, 1);
            result.SetPixels(pix);
            result.Apply();
            _BigHeaderLabel.normal.background = result;
            _BigHeaderLabel.normal.textColor = Color.white;

            return _BigHeaderLabel;
      }
    }
    static public void XXHeaderBig(string header, string tooltip = null)
    {
      GUILayout.Space(10);
      GUIContent content = new GUIContent(header, tooltip);
      Rect rc = GUILayoutUtility.GetRect(content, BigHeaderLabel);
      EditorGUI.LabelField(rc, content, BigHeaderLabel);
    }
}
变量库,这个脚本只需要一个 不用每个Shader搞一个,所有变量都放这里就够了
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;


public class XXShaderGUI : ShaderGUI
{
    public class Features
    {
      public bool useNoise;
      public bool isEnglish;
      public bool UseNoiseRotateAngle;
      public bool isDecal;
    }
    public class Property
    {
      public MaterialProperty Ztest;
      public MaterialProperty StencilComp;
      public MaterialProperty TexColor;
      public MaterialProperty TexColorIntensity;
      public MaterialProperty BaseTexture;
      public MaterialProperty BaseUV_Panner;
      public MaterialProperty UseMuBase;
      public MaterialProperty NoiseTexture;
      public MaterialProperty NoiseUV_Panner;
      public MaterialProperty NoiseScale;
      public MaterialProperty UseNoiseRotate;
      public MaterialProperty NoiseRotate;
      public MaterialProperty NoiseForParticle;
      public MaterialProperty NoiseUV1ORUV2;
    }
}逐个变量对应,体力活
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEditor;

public class XXVFXShaderGUI : XXShaderGUI
{

    Property _props = new Property();
    Features _features = new Features();
    private void UpdateProperties(MaterialProperty[] properties)
    {
      _props.Ztest = FindProperty("_Ztest", properties);   
      _props.StencilComp = FindProperty("_StencilComp", properties);      
      _props.TexColor = FindProperty("_TexColor", properties);
      _props.TexColorIntensity = FindProperty("_TexColorIntensity", properties);
      _props.BaseTexture = FindProperty("_BaseTexture", properties);
      _props.BaseUV_Panner = FindProperty("_BaseUV_Panner", properties);
      _props.UseMuBase = FindProperty("_UseMuBase", properties);
      _props.NoiseTexture = FindProperty("_NoiseTexture", properties);
      _props.NoiseUV_Panner = FindProperty("_NoiseUV_Panner", properties);
      _props.NoiseScale = FindProperty("_NoiseSacle", properties);
      _props.UseNoiseRotate = FindProperty("_UseNosieRotato", properties);
      _props.NoiseRotate = FindProperty("_NoiseRotato", properties);
      _props.NoiseForParticle = FindProperty("_NoiseForParticle", properties);
      _props.NoiseUV1ORUV2 = FindProperty("_NoiseUV1OR2", properties);
    }
    private static void ApplyKeyword(Material material, string keyword, bool toggle)
    {
      if (toggle) material.EnableKeyword(keyword);
      else material.DisableKeyword(keyword);
    }
    private void UseNoiseRegion(MaterialEditor materialEditor, Material material)
    {
      _features.useNoise = material.IsKeywordEnabled("_USENOISE_ON");
      string NotUse; string InUse; string Popup; NotUse = _features.isEnglish ? "NO" : "停用"; InUse = _features.isEnglish ? "YES" : "启用"; Popup = _features.isEnglish ? "UseNoise" : "使用噪波";
      _features.useNoise = EditorGUILayout.Popup(Popup, _features.useNoise ? 1 : 0, new string[] { NotUse, InUse }) > 0;
      ApplyKeyword(material, "_USENOISE_ON", _features.useNoise);
      if (_features.useNoise)
      {
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { string str = _features.isEnglish ? "NoiseTexture" : "噪波贴图"; materialEditor.ShaderProperty(_props.NoiseTexture, new GUIContent(str)); }
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { string str = _features.isEnglish ? "NoiseUV_Panner" : "噪波UV流动"; materialEditor.ShaderProperty(_props.NoiseUV_Panner, new GUIContent(str)); }
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { string str = _features.isEnglish ? "NoiseScale" : "噪波尺寸"; materialEditor.ShaderProperty(_props.NoiseScale, new GUIContent(str)); }
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { string str = _features.isEnglish ? "NoiseForParticle" : "给粒子的噪波"; materialEditor.ShaderProperty(_props.NoiseForParticle, new GUIContent(str)); }
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { string str = _features.isEnglish ? "NoiseUV1ORUV2" : "用噪波做顶点偏移吗"; materialEditor.ShaderProperty(_props.NoiseUV1ORUV2, new GUIContent(str)); }

            using (new EditorGUILayout.VerticalScope("helpbox"))
            { UseNoiseRotateAngleRegion(materialEditor, material); }
      }
    }
    private void UseNoiseRotateAngleRegion(MaterialEditor materialEditor, Material material)
    {
      _features.UseNoiseRotateAngle = material.IsKeywordEnabled("_USENOISEROTATEANGLE_ON");
      string NotUse; string InUse; string Popup; NotUse = _features.isEnglish ? "NO" : "停用"; InUse = _features.isEnglish ? "YES" : "启用"; Popup = _features.isEnglish ? "UseNoiseRotateAngle" : "使用噪波旋转角度";
      _features.UseNoiseRotateAngle = EditorGUILayout.Popup(Popup, _features.UseNoiseRotateAngle ? 1 : 0, new string[] { NotUse, InUse }) > 0;
      ApplyKeyword(material, "_USENOISEROTATEANGLE_ON", _features.UseNoiseRotateAngle);
      if (_features.UseNoiseRotateAngle)
      {
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { string str = _features.isEnglish ? "NoiseRotate" : "噪波UV旋转"; materialEditor.ShaderProperty(_props.NoiseRotate, new GUIContent(str)); }
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { string str = _features.isEnglish ? "UseNoiseRotate" : "使用噪波旋转"; materialEditor.ShaderProperty(_props.UseNoiseRotate, new GUIContent(str)); }
   
      }
    }

    private void IsDecalRegion(MaterialEditor materialEditor, Material material)
    {
      _features.isDecal = material.IsKeywordEnabled("_ISDECAL_ON");
      string NotUse; string InUse; string Popup; NotUse = _features.isEnglish ? "NO" : "停用"; InUse = _features.isEnglish ? "YES" : "启用"; Popup = _features.isEnglish ? "IsDecal" : "是贴花吗";
      _features.isDecal = EditorGUILayout.Popup(Popup, _features.isDecal ? 1 : 0, new string[] { NotUse, InUse }) > 0;
      ApplyKeyword(material, "_ISDECAL_ON", _features.isDecal);
      if(_features.isDecal)
      {
            material.SetFloat("_Ztest", 0);
            material.SetFloat("_StencilComp", 3);
      }
      else
      {
            material.SetFloat("_Ztest", 4);
      }
    }


    private void IsEnglishRegion(MaterialEditor materialEditor, Material material)
    {
      _features.isEnglish = material.IsKeywordEnabled("_ISENGLISH_ON");
      _features.isEnglish = EditorGUILayout.Popup("IsEnglish", _features.isEnglish ? 1 : 0, new string[] { "NO", "YES" }) > 0;
      ApplyKeyword(material, "_ISENGLISH_ON", _features.isEnglish);
    }
    public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
    {
      XXVFXGUIHelper.DissError = false;
      var material = materialEditor.target as Material;

      UpdateProperties(properties);

      using (new EditorGUILayout.VerticalScope("helpbox"))
      { IsEnglishRegion(materialEditor, material); }
      string General = _features.isEnglish ? "General" : "基础属性";
      XXVFXGUIHelper.XXHeaderBig(General, "");
      using (new EditorGUILayout.VerticalScope("helpbox"))
      {
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { string str = _features.isEnglish ? "TexColor" : "贴图颜色"; materialEditor.ShaderProperty(_props.TexColor, new GUIContent(str)); }
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { string str = _features.isEnglish ? "TexColorIntensity" : "贴图颜色强度"; materialEditor.ShaderProperty(_props.TexColorIntensity, new GUIContent(str)); }
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { string str = _features.isEnglish ? "BaseTexture" : "基础贴图"; materialEditor.ShaderProperty(_props.BaseTexture, new GUIContent(str)); }
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { string str = _features.isEnglish ? "BaseUV_Panner" : "基础UV流动"; materialEditor.ShaderProperty(_props.BaseUV_Panner, new GUIContent(str)); }
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { string str = _features.isEnglish ? "UseMuBase" : "基础图乘猛一点"; materialEditor.ShaderProperty(_props.UseMuBase, new GUIContent(str)); }
            using (new EditorGUILayout.VerticalScope("helpbox"))
            { IsDecalRegion(materialEditor, material); }
      }

      string Noise = _features.isEnglish ? "Noise" : "噪波";
      XXVFXGUIHelper.XXHeaderBig(Noise, "");
      using (new EditorGUILayout.VerticalScope("helpbox"))
      {
            UseNoiseRegion(materialEditor, material);
      }
    }
}成品:




其他可能:
因为绘制模块创建的是Texture2D,所以可以玩的很花,比如我的Shader里有一个情况是某2个变体不能同时开启,我在GUI里做了呼吸红色的报警功能
页: [1]
查看完整版本: Unity-Shading-ShaderGUI