在Unity中自动为脚本添加自定义编辑器的快捷方式

时间:2018-05-06 18:26:28

标签: c# unity3d unity-editor

Assets的Unity上下文菜单有各种有用的快捷方式,但没有快捷方式可以快速创建自定义编辑器。相反,如果我想创建一个自定义编辑器,我必须经历所有这些恼人的样板步骤:

  1. 创建Editor目录(如果尚未创建),并转到右侧子目录
  2. Create - > C# Script(实际上应该称为C# Component Script
  3. 删除所有MonoBehavior内容
  4. 添加using UnityEditor
  5. 添加CustomEditor属性
  6. 继承自Editor
  7. ......才能真正开始写我的东西......

    那个地方有快捷方式吗?

1 个答案:

答案 0 :(得分:4)

新增“添加自定义编辑器”MenuItem

我写了this little script,在Add Custom Editor上下文菜单中添加了新的Assets MenuItem

new MenuItem

单击时,它将自动在Editor文件夹中创建具有相同名称和相同相对路径的新Scripts/Editor脚本,选择它并在GUI中突出显示它。

下面的屏幕截图显示了一个示例:给定脚本Scripts/Test/TestScript,它会在Scripts/Editor/Test/TestScriptEditor创建一个新编辑器。

after using it

说明

  1. Create - > C# Script
  2. 将其称为AddCustomEditorMenuItem
  3. 使用this gist
  4. 中的代码替换其内容
  5. 完成!
  6. 测试:右键单击Scripts目录中的脚本文件。
  7. 注意:除非您选择了一个脚本,否则将禁用MenuItem ...

    1. 结束.cs个文件
    2. 位于Scripts文件夹下的某个位置(可以嵌套在任何子目录中)
    3. 不在Editor文件夹
    4. 还没有编辑
    5. 代码亮点

      • 大部分时间都要弄清楚所有路径:
      scriptName = scriptAsset.name;
      
      // get system file path
      scriptPath = Path.GetFullPath(ProjectRoot + AssetDatabase.GetAssetPath (scriptAsset));
      
      // get file name of the editor file
      editorFileName = GetEditorFileNameFor (scriptName);
      
      // split the script path
      var results = scriptPathRegex.Matches (scriptPath).GetEnumerator ();
      results.MoveNext ();
      var match = (Match)results.Current;
      scriptsPath = match.Groups [1].Value;
      scriptRelativePath = match.Groups [2].Value;
      
      // re-combine editor path
      editorPath = Path.Combine (scriptsPath, "Editor");
      editorPath = Path.Combine (editorPath, scriptRelativePath);
      editorPath = Path.Combine (editorPath, editorFileName);
      
      // nicely formatted file path
      editorPath = Path.GetFullPath(editorPath);
      editorRelativeAssetPath = editorPath.Substring(ProjectRoot.Length);
      
      • 一旦找到路径,实际上写文件很简单!
      public void WriteCustomEditorFile ()
      {
        // create all missing directories in the hierarchy
        Directory.CreateDirectory (Path.GetDirectoryName (editorPath));
      
        // write file
        File.WriteAllText (editorPath, BuildCustomEditorCode(scriptName));
      
        // let Asset DB pick up the new file
        AssetDatabase.Refresh();
      
        // highlight in GUI
        var os = AssetDatabase.LoadAllAssetsAtPath(editorRelativeAssetPath);
        EditorGUIUtility.PingObject (os[0]);
      
        // log
        Debug.Log("Created new custom Editor at: " + editorRelativeAssetPath);
      }
      
      // ...
      
      /// <summary>
      /// The menu item entry
      /// </summary>
      [MenuItem ("Assets/Add Custom Editor %#e", false, 0)]
      public static void AddCustomEditor ()
      {
        var scriptAsset = Selection.activeObject;
      
        // figure out paths
        var scriptPathInfo = new ScriptPathInfo (scriptAsset);
      
        // write file
        scriptPathInfo.WriteCustomEditorFile ();
      }
      
      • 如果您不喜欢新创建的编辑器的默认内容,请随时编辑此部分:
      static string BuildCustomEditorCode (string name)
      {
        return @"using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      using UnityEditor;
      [CustomEditor(typeof(" + name + @"))]
      public class " + name + @"Editor : Editor {
      
      public override void OnInspectorGUI ()
      {
        base.OnInspectorGUI ();
        var obj = (" + name + @") target;
        if (GUILayout.Button (""Hi!"")) {
          // do something with obj when button is clicked
          Debug.Log(""Button pressed for: "" + obj.name);
          EditorGUIUtility.PingObject (obj);
        }
      }
      }";
      }
      
      • 如果您的菜单项始终显示为灰色,请先调查上面的解释,然后再调试确定是否选择了有效脚本的代码:
      [MenuItem ("Assets/Add Custom Editor %#e", true, 0)]
      public static bool ValidateAddCustomEditor ()
      {
        var scriptAsset = Selection.activeObject;
      
        if (scriptAsset == null) {
          // nothing selected? (should probably not happen)
          return false;
        }
      
        var path = ProjectRoot + AssetDatabase.GetAssetPath (scriptAsset);
      
        if (!scriptPathRegex.IsMatch (path)) {
          // not a Script in the Script folder
          return false;
        }
      
        if (editorScriptPathRegex.IsMatch (path)) {
          // we are not interested in Editor scripts
          return false;
        }
      
      
        if (Directory.Exists (path)) {
          // it's a directory, but we want a file
          return false;
        }
      
        var scriptPathInfo = new ScriptPathInfo (scriptAsset);
      
        //        Debug.Log (scriptPathInfo.scriptPath);
        //        Debug.Log (Path.GetFullPath(AssetsPath + "/../"));
        //        Debug.Log (scriptPathInfo.editorRelativeAssetPath);
        //        Debug.Log (scriptPathInfo.editorPath);
      
        if (File.Exists (scriptPathInfo.editorPath)) {
          // editor has already been created
          return false;
        }
      
        // all good!
        return true;
      }