问题

unity中创建新的shader时,不能直接创建自定义的shader模板,每次都需要替换

创建新的自定义shader

  • 需求:创建新的shader时,不能直接创建自定义的shader模板,每次都需要替换

  • 解决之道:写入一个shader 模板信息到stream并写入到Asset中,随后再自定义一个菜单按钮来创建shader

  • 实现

    using UnityEngine;
    using UnityEditor;
    using System;
    using System.IO;
    using System.Text;
    using UnityEditor.ProjectWindowCallback;
    using System.Text.RegularExpressions;
    
    public class ElysiaCreateShader
    {
      public const string m_PBRShaderTemplatePath = "Assets/Materials/PBR/S_PBR.shader";
    
      [MenuItem("Assets/Create/Elysia/PBR Shader")]
      public static void CreateShaderTemplate()
      {
          // 资源重命名
          ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0,
              ScriptableObject.CreateInstance<ElysiaShaderAsset>(),
              GetSelectedDirectoryPath() + "/S_PBR.shader",
              null,
              m_PBRShaderTemplatePath
              ); 
      }
    
      // 获取文件夹路径
      public static string GetSelectedDirectoryPath()
      {
          string path = "";
    
          // 获取选中物体的路径
          foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets))
          {
              path = AssetDatabase.GetAssetPath(obj);
              if (!string.IsNullOrEmpty(path) && File.Exists(path))
              {
                  path = Path.GetDirectoryName(path);
              }
          }
    
          return path;
      }
    
    
    }
    
    class ElysiaShaderAsset : EndNameEditAction
    {
      public override void Action(int instanceId, string pathName, string resourceFile)
      {
          UnityEngine.Object o = CreateAssetFromTemplate(pathName, resourceFile);
          ProjectWindowUtil.ShowCreatedAsset(o);  // 在Inspector视图中自动打开并选中
      }
    
      static UnityEngine.Object CreateAssetFromTemplate(string pathName, string resourceFile)
      {
          string fullPathName = Path.GetFullPath(pathName);
    
          // 读取shader模板内容
          StreamReader streamReader = new StreamReader(resourceFile);
          string text = streamReader.ReadToEnd();
          streamReader.Close();
    
          string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(pathName);   // 去除文件后缀名
          text = Regex.Replace(text, "#NAME#", fileNameWithoutExtension); // 把模板的#NAME#替换为文件名
    
          // 编码UTF8
          bool bEncoderShouldEmitUTF8Identifier = true;
          bool bThrowOnInvalidBytes = false;
          UTF8Encoding utf8Encoding = new UTF8Encoding(bEncoderShouldEmitUTF8Identifier, bThrowOnInvalidBytes);
    
          // 写入文件
          bool append = false;    // 全部重写
          StreamWriter streamWriter = new StreamWriter(fullPathName, append, utf8Encoding);
          streamWriter.Write(text);
          streamWriter.Close();
    
          // 导入Asset
          AssetDatabase.ImportAsset(pathName);
          return AssetDatabase.LoadAssetAtPath(pathName, typeof(UnityEngine.Object));
      }
    }
    
    

他们曾如此骄傲的活过,贯彻始终