Skip to content

Instantly share code, notes, and snippets.

@KevinThielen
Last active July 24, 2024 13:21
Show Gist options
  • Save KevinThielen/e10621e299920a2b2576ffb13dcf6dd1 to your computer and use it in GitHub Desktop.
Save KevinThielen/e10621e299920a2b2576ffb13dcf6dd1 to your computer and use it in GitHub Desktop.
[Unity] Create MenuItems dynamically to add/remove preprocessor macros.
using UnityEngine;
using UnityEditor;
using System.Text;
namespace MyUtil
{
[InitializeOnLoad]
public partial class CustomDefines
{
private const string ScriptPath = "/Util/Editor/MyDefines.cs"; //path including the name of to the (to be) generated File
private const string MENU = "CustomDefines/"; //name of the menu tab where all menuitems will be accessed
private static readonly string[] DEFINES = { //all custom global defines come here
"DEBUG_LOG",
"ENABLE_ANALYTICS",
"RUN_TESTS",
"USE_MOCKUP_SERVER"
};
static CustomDefines() {
GenerateItems();
//Wait for Unity to be ready
EditorApplication.delayCall += () => {
UpdateCheckedAll();
};
}
public static void GenerateItems()
{
string filePath = Application.dataPath + ScriptPath;
StringBuilder builder = new StringBuilder();
builder.AppendLine("/******************");
builder.AppendLine("* AUTO GENERATED *");
builder.AppendLine("/*******************/");
builder.AppendLine("");
builder.AppendLine("using UnityEngine;");
builder.AppendLine("using UnityEditor;");
builder.AppendLine("\nnamespace MyUtil");
builder.AppendLine("{");
builder.AppendLine("\tpublic partial class CustomDefines");
builder.AppendLine("\t{");
string updateCheckedAllMethod = "\t\tstatic partial void UpdateCheckedAll() {"; //Update marker AFTER the generated file was imported by Unity
for(int i = 0; i<DEFINES.Length; ++i) {
builder.AppendLine("\t\t[MenuItem(\""+ MENU + DEFINES[i] +"\")]");
builder.AppendLine("\t\tpublic static void Toggle"+ DEFINES[i] +"() { ");
builder.AppendLine("\t\t\tToggleDefine(\""+DEFINES[i]+"\");");
builder.AppendLine("\t\t}\n");
updateCheckedAllMethod += "\n\t\t\tUpdateChecked(\""+ DEFINES[i] +"\");";
}
updateCheckedAllMethod += "\n\t\t}\n";
builder.Append(updateCheckedAllMethod);
builder.AppendLine("\t}");
builder.AppendLine("}");
System.IO.File.WriteAllText(filePath, builder.ToString());
AssetDatabase.Refresh();
}
public static void ToggleDefine(string define) {
// ";" added as pre- and postfix to not care about about substrings in defines.
string symbols = ";"+PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone)+";";
if (!symbols.Contains(";"+define+";")) {
PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, symbols + define);
Menu.SetChecked(MENU+define, true);
}
else {
symbols = symbols.Replace(";"+define+";", ";");
PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, symbols);
Menu.SetChecked(MENU+define, false);
}
}
static partial void UpdateCheckedAll();
public static void UpdateChecked(string define) {
string symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone);
Menu.SetChecked(MENU+define, symbols.Contains(define));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment