Новый «Добавить пользовательский редактор» MenuItem
Я написал этот маленький скрипт , который добавляет новый Add Custom Editor
MenuItem в контекстное меню Assets
:
При нажатии он автоматически создаст новый скрипт Editor
с тем же именем и тем же относительным путем в папке Scripts/Editor
, выберите его и выделите его в графическом интерфейсе.
На приведенных ниже снимках экрана показан пример: данный скрипт Scripts/Test/TestScript
создает новый редактор на Scripts/Editor/Test/TestScriptEditor
.
Инструкция
Create
-> C# Script
- Назовите это
AddCustomEditorMenuItem
- Заменить его содержимое кодом из этой сущности
- Готово!
- Проверьте это: щелкните правой кнопкой мыши файл сценария в каталоге
Scripts
.
ПРИМЕЧАНИЕ : Элемент MenuItem будет отключен, если вы не выбрали сценарий, который ...
- Имеет
.cs
окончание файла
- Находится где-то в папке
Scripts
(может быть вложен в любой подкаталог)
- Нет в папке
Editor
- Редактора пока нет
Основные характеристики кода
- Вычисление всех путей заняло большую часть времени:
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;
}