Editorscript: Generate enum from string[]

I’m wondering if it’s possible to Generate an enum in an Editorscript?

I have a method in an Editorscript that dynamically creates a string. Let’s say holds the strings “Foo”, “Goo” and “Hoo”. Is it possible, from that array, to generate an enum, like the following:

public enum MyEnum
{
Foo,
Goo,
Hoo
}

I guess Unity will have to recompile after that. When recompiling is done, the enum should be ready to be used in PlayMode.

Is that by any means possible?
Any input is most welcome :slight_smile:

Though @TimHeijden’s code works like a charm (and got me in the right direction) I ended up doing it like this:

#if UNITY_EDITOR
using UnityEditor;
using System.IO;

public class GenerateEnum
{
	[MenuItem( "Tools/GenerateEnum" )]
	public static void Go()
	{
		string enumName = "MyEnum";
		string[] enumEntries = { "Foo", "Goo", "Hoo" };
		string filePathAndName = "Assets/Scripts/Enums/" + enumName + ".cs"; //The folder Scripts/Enums/ is expected to exist

		using ( StreamWriter streamWriter = new StreamWriter( filePathAndName ) )
		{
			streamWriter.WriteLine( "public enum " + enumName );
			streamWriter.WriteLine( "{" );
			for( int i = 0; i < enumEntries.Length; i++ )
			{
				streamWriter.WriteLine( "	" + enumEntries *+ "," );*
  •  	}*
    
  •  	streamWriter.WriteLine( "}" );*
    
  •  }*
    
  •  AssetDatabase.Refresh();*
    
  • }*
    }
    #endif

It’s actually quite simple if you want to do this in an editor script. Like any text file, you can use a StringBuilder to create the contents:

string enumNam = "MyEnum";
string[] enumEntries = new string[] { "Foo", "Goo", "Hoo" };

StringBuilder str = new StringBuilder();
str.AppendFormat(@"public enum {0}

{
“, enumName);
for (int i = 0; i < enumEntries.Length; i++)
{
str.AppendFormat(@”{0},
", enumEntries*);*
}
str.AppendLine(@“}”);
Then, use some UnityEditor classes to get the asset path. For example:
string path = AssetDatabase.GetAssetPath(serializedObject.targetObject);
path = path.Substring(0, path.Length - Path.GetExtension(path).Length) + “.cs”;
File.WriteAllText(path, str.ToString());
AssetDatabase.ImportAsset(path);
And that should be it! (note: depending on what kind of editor script you want to write, you may need to use a different way to get the paths, but there are loads of ways to that easily found with google.

Another thing you may want to do is ensure the strings don’t contain any invalid characters or keywords that would break in C#. So you can combine some of the other answers here with something like this:

private static HashSet<string> csharpKeywords = new HashSet<string> {
	"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked",
	"class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else",
	"enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for",
	"foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock",
	"long", "namespace", "new", "null", "object", "operator", "out", "override", "params",
	"private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed",
	"short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw",
	"true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using",
	"virtual", "void", "volatile", "while"
};

// given a string, attempts to make the string compatible with an enum
static string MakeStringEnumCompatible(string text)
{
	if (text.Length <= 0) { return "INVALID_ENUM_NAME"; }
	string ret = "";

	// first char must be a letter or an underscore
	if (char.IsLetter(text[0]) || (text[0] == '_')) { ret += text[0]; }

	// strip out anything that's not a digit or underscore
	for (int i = 1; i < text.Length; ++i) {
		if (char.IsLetterOrDigit(text<em>) || (text <em>== '_')) { ret += text*; }*</em></em>

* }*
* if (ret.Length <= 0) { return “INVALID_ENUM_NAME”; }
_ // all the keywords are lowercase, so if we just change the first letter to uppercase,
// then there will be no conflict*
* if (csharpKeywords.Contains(ret)) { ret = char.ToUpper(ret[0]) + ret.Substring(1); }*_

* return ret;*
* }*

Here is youtube tutorial how to show List as Enum in inspector

158744-gif.gif

158744-gif.gif