简体   繁体   English

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

[英]Shortcut to automatically add custom editor for Script in Unity

The Unity context menu for Assets has all kinds of useful shortcuts, but there is no shortcut to quickly create a custom editor. Assets 的 Unity 上下文菜单有各种有用的快捷方式,但没有快捷方式可以快速创建自定义编辑器。 Instead, if I want to create a custom editor, I have to go through all these annoying boilerplate steps:相反,如果我想创建一个自定义编辑器,我必须经历所有这些烦人的样板步骤:

  1. Create Editor directory (if not created yet), and go to the right sub-directory创建Editor目录(如果还没有创建),然后转到正确的子目录
  2. Create -> C# Script (which should actually be called C# Component Script ) Create -> C# Script (实际上应该称为C# Component Script
  3. Remove all the MonoBehavior stuff删除所有MonoBehavior东西
  4. Append Editor to the class nameEditor附加到类名
  5. Add using UnityEditor using UnityEditor添加
  6. Add the CustomEditor attribute添加自CustomEditor属性
  7. Inherit from EditorEditor继承

...before being able to actually start writing my stuff... ......在能够真正开始写我的东西之前......

Is there a shortcut for that somewhere?某处有捷径吗?

New "Add Custom Editor" MenuItem新的“添加自定义编辑器”菜单项

I wrotethis little script which adds a new Add Custom Editor MenuItem to the Assets context menu:我编写了这个小脚本,它向Assets上下文菜单Add Custom Editor了一个新的Add Custom Editor MenuItem

新菜单项

Usage用法

  1. Right-click a Component script in the Scripts folder.右键单击Scripts文件夹中的Component脚本。
  2. Select Add Custom Editor .选择Add Custom Editor
  3. The component now has an Editor which gets automatically selected, so you can modify it as you like.该组件现在有一个自动选择的Editor ,因此您可以根据需要对其进行修改。 It has the same name (with Editor appended) and is at the same relative path, but in the Scripts/Editor folder它具有相同的名称(附加了Editor )并且位于相同的相对路径中,但是在Scripts/Editor文件夹中

The screenshots below show an example: Given script Scripts/Test/TestScript , it creates a new editor at Scripts/Editor/Test/TestScriptEditor .下面的屏幕截图显示了一个示例:给定脚本Scripts/Test/TestScript ,它会在Scripts/Editor/Test/TestScriptEditor处创建一个新编辑Scripts/Editor/Test/TestScriptEditor

NOTE : The MenuItem will be disabled unless you have selected a Script that:注意:除非您选择了以下脚本,否则 MenuItem 将被禁用:

  1. Has a .cs file ending有一个.cs文件结尾
  2. Is located somewhere under the Scripts folder (can be nested in any sub-directory)位于Scripts文件夹下的某处(可以嵌套在任何子目录中)
  3. Is not in the Editor folder不在Editor文件夹中
  4. Does not have an editor yet还没有编辑器

使用后

Setup设置

  1. Create -> C# Script Create -> C# Script
  2. Call it AddCustomEditorMenuItem称之为AddCustomEditorMenuItem
  3. Replace its contents with the code fromthis gist此要点中的代码替换其内容
  4. Done!完毕!
  5. Test it: Right-click a script file in the Scripts directory.测试: 右键单击Scripts目录中的Scripts文件。

Code Highlights代码亮点

  • Figuring out all the paths took most of the time:找出所有路径花费了大部分时间:
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);
  • Once, paths are figured out, actually writing the file is nice and easy!一旦找到路径,实际编写文件就很简单了!
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 ();
}
  • If you don't like the default contents of a newly created editor, feel free to edit this part:如果您不喜欢新创建的编辑器的默认内容,请随意编辑此部分:
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);
  }
}
}";
}
  • If your menu item is always grayed out, consider first checking out my explanations above, before debugging the code that determines if a valid script is selected:如果您的菜单项始终显示为灰色,请考虑先查看我上面的解释,然后再调试确定是否选择了有效脚本的代码:
[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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM