Skip to content

Instantly share code, notes, and snippets.

@tomkail
Last active July 13, 2023 12:39
Show Gist options
  • Save tomkail/a1cdd11cd32920f832f85be802e31daa to your computer and use it in GitHub Desktop.
Save tomkail/a1cdd11cd32920f832f85be802e31daa to your computer and use it in GitHub Desktop.
Adds "Create > Editor Script" menu to scripts a right click that automatically creates editor scripts.
using System;
using System.Globalization;
using System.Text;
using System.IO;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.ProjectWindowCallback;
public static class CreateEditorScriptMenuItem {
const string fileNameTemplate = "{0}Editor.cs";
const string template = "using UnityEngine;\nusing UnityEditor;\n\n[CustomEditor(typeof({0}))]\npublic class {0}Editor : Editor {{\n\tpublic override void OnInspectorGUI () {{\n\t\tbase.OnInspectorGUI();\n\t}}\n}}";
[MenuItem("Assets/Create/Editor Script", true)]
public static bool CreateEditorScriptValidator () {
if (Selection.activeObject == null || !(Selection.activeObject is MonoScript)) return false;
var typeName = Selection.activeObject.name;
string fileName = string.Format(fileNameTemplate, typeName);
var directoryPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(Selection.activeObject));
string path = directoryPath+"/Editor/"+fileName;
var asset = AssetDatabase.LoadAssetAtPath<Object>(path);
return asset == null;
}
[MenuItem("Assets/Create/Editor Script", false, 81)]
public static void CreateEditorScript () {
var typeName = Selection.activeObject.name;
var directoryPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(Selection.activeObject));
var targetDirectoryPath = directoryPath+"/Editor";
if(!AssetDatabase.GetSubFolders(directoryPath).Contains(targetDirectoryPath)) {
AssetDatabase.CreateFolder(directoryPath, "Editor");
AssetDatabase.LoadAssetAtPath<DefaultAsset>(targetDirectoryPath);
}
string fileName = string.Format(fileNameTemplate, typeName);
string contents = string.Format(template, typeName);
string filePath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(targetDirectoryPath, fileName));
ScriptAssetCreator.CreateNewFile(filePath, contents);
}
}
public static class ScriptAssetCreator {
public static void CreateNewFile (string filePath, string text) {
CreateScriptAssetFromTemplate(filePath, text);
}
public static void CreateNewFileAndStartNameEditing (string filePath, string text) {
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<CreateScriptAssetAction>(), filePath, null, text);
}
public static UnityEngine.Object CreateScriptAssetFromTemplate(string filePath, string text) {
string fullPath = Path.GetFullPath(filePath);
UTF8Encoding encoding = new UTF8Encoding(true, false);
bool append = false;
StreamWriter streamWriter = new StreamWriter(fullPath, append, encoding);
streamWriter.Write(text);
streamWriter.Close();
AssetDatabase.ImportAsset(filePath);
return AssetDatabase.LoadAssetAtPath(filePath, typeof(DefaultAsset));
}
class CreateScriptAssetAction : EndNameEditAction {
public override void Action(int instanceId, string filePath, string text) {
UnityEngine.Object asset = CreateScriptAssetFromTemplate(filePath, text);
ProjectWindowUtil.ShowCreatedAsset(asset);
}
}
// Gets a camelCase variable name from a string
public static string ToCamelCase(string text) {
List<char> outputList = new List<char>();
char[] a = text.ToLower().ToCharArray();
for (int i = 0; i < a.Length; i++) {
if(a[i] == ' ') continue;
if(i == 0) outputList.Add(char.ToLower(a[i]));
else if(a[i-1] == ' ') outputList.Add(char.ToUpper(a[i]));
else outputList.Add(a[i]);
}
return new string(outputList.ToArray());
}
}
@bcg-andrew
Copy link

Cool gist What/where is ScriptAssetCreator ?

@tomkail
Copy link
Author

tomkail commented May 24, 2021

Oh well noticed! I've updated it. Not tested though!

@bcg-andrew
Copy link

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment