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

标签 c# unity3d unity-editor

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

  1. 创建Editor目录(如果还没有创建),并转到正确的子目录
  2. Create -> C# Script(实际上应该叫做C# Component Script)
  3. 删除所有 MonoBehavior 东西
  4. Editor附加到类名
  5. 添加使用UnityEditor
  6. 添加CustomEditor属性
  7. 继承自 Editor

...在能够真正开始写我的东西之前...

在某处有快捷方式吗?

最佳答案

新的“添加自定义编辑器”菜单项

我写了this little script它添加了一个新的 Add Custom Editor MenuItemAssets 上下文菜单:

new MenuItem

用法

  1. 右键单击 Scripts 文件夹中的 Component 脚本。
  2. 选择添加自定义编辑器
  3. 组件现在有一个自动选择的编辑器,因此您可以随意修改它。它具有相同的名称(附加了 Editor)并且位于相同的相对路径中,但在 Scripts/Editor 文件夹中

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

注意:菜单项将被禁用,除非您选择了一个脚本:

  1. 有一个.cs文件结尾
  2. 位于 Scripts 文件夹下的某处(可以嵌套在任何子目录中)
  3. 不在 Editor 文件夹中
  4. 还没有编辑

after using it

设置

  1. 创建 -> C# 脚本
  2. 将其命名为 AddCustomEditorMenuItem
  3. this gist 中的代码替换其内容
  4. 完成!
  5. 测试:右键单击 Scripts 目录中的脚本文件。

代码亮点

  • 找出所有路径花费了大部分时间:
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;
}

关于c# - 在 Unity 中自动为脚本添加自定义编辑器的快捷方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50203145/

相关文章:

c# - 如何通过代码让一个GameObject颠倒过来?

c# - 在 Unity 中,如何将值从一个脚本传递到另一个脚本?

c# - 如何获取当前目录的路径? (ScriptableObject, UnityEditor.AssetDatabase)

c# - Session "X"是独立于用户的还是定义了同一用户的不同 session ?

c# - 如何实现简单的多线程功能

c# - 如何删除 Unity3D 中按钮之间的间距?

unity3d - 如何以一种可以调整一个游戏对象的克隆属性以匹配场景 View 中的所有其他游戏对象的方式克隆多个游戏对象

unity3d - unity 条件字段自定义编辑器

c# - 一次写入多次读取的多线程是否需要 volatile?

c# - 网络CHM文件