技术笔记(10)Unity编辑器扩展

技术笔记(10)Unity编辑器扩展

  • 希望实现的功能或目标:

    • 编写一个编辑器扩展功能,用以快速创建Event和Command脚本

  • 学习笔记:

    • CreateScriptWindow类

      • 继承EditorWindow类

      • 用两个常量字符串,记录模板所在的文件路径

        • const string EVENTTEMPLATE_PATH = "Assets/Scripts/GameFramework/ReusableCode/Layers/Utility/Editor/EventTemplateScript.txt";
          const string COMMANDTEMPLATE_PATH = "Assets/Scripts/GameFramework/ReusableCode/Layers/Utility/Editor/CommandTemplateScript.txt";
          
      • 调用MenuItem选择新增按钮的索引位置

        • [MenuItem("Assets/Create/C# Event Script(Command)")]
      • AssetsCreate方法:调用GetWindow方法,得到一个当前类名的window,并调用这个window的Show方法

        •     static void AssetsCreate()
              {
                  CreateScriptWindow window = (CreateScriptWindow)GetWindow(typeof(CreateScriptWindow), false, "创建C#");
                  window.Show(true);
              }
          
      • 两个普通字符串

        •     string _scriptName;
              string _description;
          
      • OnGUI方法

        • 通过GetPath方法获取当前所选的目录

        • 在Directory中查询该目录是否存在

          • 如果存在,则创建一个TextField用来输入脚本名。

            • 然后创建一个“创建事件”按钮

            • 如果创建成功了,设置要生成的脚本的路径,并展示出来

              • 检测输入的脚本名是否正确,是否已有同名脚本并报错
              • 如果都没问题,把模板里的内容读出来,把所有的“My”替换成输入的脚本名,并以UTF8的编码格式写到新生成的脚本里
              • 刷新project列表,显示创建成功的提示信息
          • 创建命令脚本的逻辑同上

        •     private void OnGUI()
              {
                  string selectDirPath = GetPath();
                  if (Directory.Exists(selectDirPath))
                  {
                      _scriptName = EditorGUILayout.TextField("脚本名:", _scriptName);
          
                      if(GUILayout.Button("创建事件", GUILayout.Height(40)))
                      {
                          string path = selectDirPath + "/" + _scriptName + "Event.cs";
                          EditorGUILayout.LabelField("路径:", path);
                          EditorGUILayout.Space();
                          if (!CheckScriptName(_scriptName))
                          {
                              ShowNotification(new GUIContent("请输入正确的脚本名!"));
                          }
                          else if(CheckRepeat(selectDirPath))
                          {
                              ShowNotification(new GUIContent("当前文件夹下已经有同名脚本!"));
                          }
                          else
                          {
                              string content = File.ReadAllText(EVENTTEMPLATE_PATH);
                              content = content.Replace("My", _scriptName);
                              File.WriteAllText(path, content, Encoding.UTF8);
                              AssetDatabase.Refresh();
                              ShowNotification(new GUIContent("Success!"));
                          }
                      }
          
                      if (GUILayout.Button("创建命令", GUILayout.Height(40)))
                      {
                          string path = selectDirPath + "/" + _scriptName + "Command.cs";
                          EditorGUILayout.LabelField("路径:", path);
                          EditorGUILayout.Space();
                          if (!CheckScriptName(_scriptName))
                          {
                              ShowNotification(new GUIContent("请输入正确的脚本名!"));
                          }
                          else if (CheckRepeat(selectDirPath))
                          {
                              ShowNotification(new GUIContent("当前文件夹下已经有同名脚本!"));
                          }
                          else
                          {
                              string content = File.ReadAllText(COMMANDTEMPLATE_PATH);
                              content = content.Replace("My", _scriptName);
                              File.WriteAllText(path, content, Encoding.UTF8);
                              AssetDatabase.Refresh();
                              ShowNotification(new GUIContent("Success!"));
                          }
                      }
                  }
                  else
                  {
                      EditorGUILayout.LabelField("请在Project面板中选择将要放置脚本的文件夹");
                  }
          
              }
          
      • CheckScriptName方法

        • 用正则表达式记录命名标准格式
        • 对输入的参数进行检测,并返回是否符合格式
        •     bool CheckScriptName(string scriptName)
              {
                  Regex regex = new Regex("^[a-zA-Z_][a-zA-Z0-9_]*$");
                  return regex.IsMatch(scriptName);
              }
          
      • CheckRepeat方法

        • 以所选路径为参数,new一个DirectoryInfo对象
        • 并用FileInfo数组存这个DirectoryInfo对象里获取到的所有文件
        • 脚本名字符串附上其格式“.cs”
        • 遍历FileInfo数组,与文件名一一进行对比,有重名则返回true,无则返回false
        •     bool CheckRepeat(string selectDirPath)
              {
                  DirectoryInfo dir = new DirectoryInfo(selectDirPath);
                  FileInfo[] files = dir.GetFiles();
                  string scriptName = _scriptName + ".cs";
                  for(int i = 0;i<files.Length;i++)
                  {
                      if (files[i].Name == scriptName)
                      {
                          return true;
                      }
                  }
                  return false;
              }
          
      • OnSelectionChange方法

        • 调用Repaint方法
      • GetPath方法

        • 调用AssetDatabase类的GetAssetPath方法,以Selection.activeInstanceID作为其参数。从而获得选中资产的相对路径
        •     private string GetPath()
              {
                  string assetPath = null;
                  if(assetPath == null || assetPath == "")
                  {
                      assetPath = AssetDatabase.GetAssetPath(Selection.activeInstanceID);
                  }
                  return assetPath;
              }
          

  • 实现过程中产生的疑惑:

    • 编辑器扩展的作用?
    • 有哪些实际的应用?

  • 对疑惑的解答:

    • 其允许我们通过自定义脚本和插件来增强和个性化unity编辑器的功能,主要作用有:

      • 提高开发效率:自动化处理重复性任务
      • 自定义工具和界面:以适应特定的开发需求,提高工作流程和效率和舒适度
      • 增强可视化编辑:绘制辅助图形、直观编辑对象属性
      • 集成第三方工具:3d建模、音视频编辑软件
    • 实际应用:

      • 可用来运行游戏特定部分,进行快速测试而无需启动整个游戏
      • 查找和替换材质、优化纹理等
      • 集成Photoshop、Blender等外部工具的功能

日期:

posted @   静候霜白  阅读(152)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示