Skip to content

Instantly share code, notes, and snippets.

@mmoczkowski
Created August 15, 2015 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmoczkowski/aadae42d8ccb23aedb9b to your computer and use it in GitHub Desktop.
Save mmoczkowski/aadae42d8ccb23aedb9b to your computer and use it in GitHub Desktop.
using UnityEngine;
using UnityEditor;
using System;
using System.Collections;
using System.IO;
using System.Text;
public class ConstantsGenerator : EditorWindow
{
private const string CLASS_HEADER = "// This class is auto-generated, do not modify.\n";
private const string FOLDER_LOCATION = "Scripts/Generated/";
private const string TAGS_FILE_NAME = "Tags";
private const string LAYERS_FILE_NAME = "Layers";
private const string SCENES_FILE_NAME = "Scenes";
private const string SCRIPT_EXTENSION = ".cs";
[MenuItem("Code Generation/Rebuild Constants")]
static void RebuildTagsAndLayersClasses()
{
string folderPath = Application.dataPath + "/" + FOLDER_LOCATION;
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
// Generate Tags class
File.WriteAllText(folderPath + TAGS_FILE_NAME + SCRIPT_EXTENSION, GetClassContent(TAGS_FILE_NAME, UnityEditorInternal.InternalEditorUtility.tags));
// Generate Layers class
File.WriteAllText(folderPath + LAYERS_FILE_NAME + SCRIPT_EXTENSION, GetLayerClassContent(LAYERS_FILE_NAME, UnityEditorInternal.InternalEditorUtility.layers));
// Generate Scenes class
File.WriteAllText(folderPath + SCENES_FILE_NAME + SCRIPT_EXTENSION, GetClassContent(SCENES_FILE_NAME, EditorBuildSettingsScenesToNameStrings(EditorBuildSettings.scenes)));
// Generate Mecanim classes
foreach(UnityEditor.Animations.AnimatorController animator in Resources.FindObjectsOfTypeAll<UnityEditor.Animations.AnimatorController>()) {
string filename = folderPath + ToUpperCaseWithUnderscores(animator.name) + SCRIPT_EXTENSION;
File.WriteAllText(filename, GetMecanimClassContent(animator));
Debug.Log("File \"" + filename + "\" generated.");
}
AssetDatabase.Refresh();
Debug.Log("Constants generated.");
}
private static string[] EditorBuildSettingsScenesToNameStrings(EditorBuildSettingsScene[] scenes)
{
string[] sceneNames = new string[scenes.Length];
for (int n = 0; n < sceneNames.Length; n++)
{
sceneNames[n] = System.IO.Path.GetFileNameWithoutExtension(scenes[n].path);
}
return sceneNames;
}
private static string GetClassContent(string className, string[] labelsArray)
{
string output = "";
output += CLASS_HEADER;
output += "public class " + className + "\n";
output += "{\n";
foreach (string label in labelsArray)
{
output += "\t"+ BuildConstVariable(label) + "\n";
}
output += "}";
return output;
}
private static string GetLayerClassContent(string className, string[] labelsArray)
{
string output = "";
output += CLASS_HEADER;
output += "public class " + className + "\n";
output += "{\n";
foreach (string label in labelsArray)
{
output += "\t" + BuildConstVariable(label) + "\n";
}
output += "\n";
foreach (string label in labelsArray)
{
output += "\t" + "public const int " + ToCamelCase(label) + "_INT" + " = " + LayerMask.NameToLayer(label) + ";\n";
}
output += "}";
return output;
}
private static string GetMecanimClassContent(UnityEditor.Animations.AnimatorController animator) {
StringBuilder builder = new StringBuilder();
builder.AppendLine(CLASS_HEADER);
builder.AppendLine("namespace Mecanim {");
builder.AppendLine("public static class " + ToUpperCaseWithUnderscores(animator.name));
builder.AppendLine("{");
foreach(UnityEngine.AnimatorControllerParameter myParam in animator.parameters) {
string paramName = myParam.name.ToUpperInvariant();
int paramHash = myParam.nameHash;
builder.AppendLine( string.Format("\tpublic const int {0} = {1};", paramName, paramHash));
}
builder.AppendLine("}");
builder.AppendLine("} // end of namespace");
return builder.ToString();
}
private static string BuildConstVariable(string varName)
{
return "public const string " + ToCamelCase(varName) + " = " + '"' + varName + '"' + ";";
}
private static string ToCamelCase(string input)
{
string output = "" + input[0];
for (int n = 1; n < input.Length; n++)
{
if ((char.IsUpper(input[n]) || input[n] == ' ') && !char.IsUpper(input[n - 1]) && input[n - 1] != '_' && input[n - 1] != ' ')
{
output += "_";
}
if (input[n] != ' ' && input[n]!='_')
{
output += input[n];
}
}
output = output.ToUpper();
return output;
}
private static string ToUpperCaseWithUnderscores(string the_string)
{
// If there are 0 or 1 characters, just return the string.
if (the_string == null) return the_string;
if (the_string.Length < 2) return the_string.ToUpper();
the_string = the_string.Replace('_', ' ');
// Split the string into words.
string[] words = the_string.Split(
new char[] { },
StringSplitOptions.RemoveEmptyEntries);
// Combine the words.
string result = "";
foreach (string word in words)
{
result +=
word.Substring(0, 1).ToUpper() +
word.Substring(1);
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment