Skip to content

Instantly share code, notes, and snippets.

@Slyp05
Created April 12, 2021 18:52
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 Slyp05/b3c2f971819180decec403b56f4ce204 to your computer and use it in GitHub Desktop.
Save Slyp05/b3c2f971819180decec403b56f4ce204 to your computer and use it in GitHub Desktop.
Meta programming in Unity - Juste Tools
using System;
using System.Collections.Generic;
using UnityEngine;
public static class AnimatorEnumExtension
{
public static Dictionary<Enum, string> floatEnumToName = new Dictionary<Enum, string>()
{
/// EXTEND_FLOAT do not delete !
};
public static void SetFloat(this Animator anim, Enum parameter, float value)
{
anim.SetFloat(floatEnumToName[parameter], value);
}
public static float GetFloat(this Animator anim, Enum parameter)
{
return anim.GetFloat(floatEnumToName[parameter]);
}
}
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Linq;
using System;
public class EnumBasedAnimatorWindow : EditorWindow
{
const string windowName = "Enum Based Animator Generator";
const string relativeAnimExtensionFileName = "/AnimatorEnumExtension.cs"; // path of the AnimatorEnumExtension script relative to Assets
Animator target;
string namespaceName;
string[] enumValueNames;
void OnGUI()
{
EditorGUI.BeginChangeCheck();
target = (Animator)EditorGUILayout.ObjectField("Target Animator", target, typeof(Animator), true);
if (EditorGUI.EndChangeCheck() && target != null)
enumValueNames = new string[target.parameters.Where((p) => p.type == AnimatorControllerParameterType.Float).ToArray().Length];
if (target != null)
{
namespaceName = EditorGUILayout.TextField("Namespace", namespaceName);
AnimatorControllerParameter[] floatParameters = target.parameters.Where((p) => p.type == AnimatorControllerParameterType.Float).ToArray();
for (int i = 0; i < floatParameters.Length; i++)
enumValueNames[i] = EditorGUILayout.TextField(floatParameters[i].name, enumValueNames[i]);
if (GUILayout.Button("Generate"))
GenerateEnumAndAddToDico();
}
}
void GenerateEnumAndAddToDico()
{
// create the enum file
string template = File.ReadAllText(MetaGenUtility.templatePath + "FloatEnum.txt");
string scriptText = string.Format(template, namespaceName, string.Join(", ", enumValueNames));
File.WriteAllText(MetaGenUtility.generatePath + $"AnimatorEnum_{target.runtimeAnimatorController.name}.cs", scriptText);
// add some entries to the floatEnumToName dictionary
AnimatorControllerParameter[] floatParameters = target.parameters.Where((p) => p.type == AnimatorControllerParameterType.Float).ToArray();
string dicoEntries = "";
for (int i = 0; i < floatParameters.Length; i++)
dicoEntries += $" {{ {namespaceName}.Float.{enumValueNames[i]}, \"{floatParameters[i].name}\" }}, {Environment.NewLine}";
dicoEntries += Environment.NewLine;
AddToFileAtMarker(Application.dataPath + relativeAnimExtensionFileName, dicoEntries, "/// EXTEND_FLOAT");
}
void AddToFileAtMarker(string fileName, string toAdd, string extendMarker)
{
string text = File.ReadAllText(fileName);
if (!text.Contains(extendMarker))
throw new FormatException(string.Format("Couldnt find marker {0} in {1} !", extendMarker, fileName));
text = text.Replace(extendMarker, toAdd + extendMarker);
File.WriteAllText(fileName, text);
}
void Awake()
{
titleContent = new GUIContent(windowName);
}
void OnDestroy()
{
AssetDatabase.Refresh();
}
[MenuItem("Juste Tools/" + windowName)]
static void Init()
{
EnumBasedAnimatorWindow window = (EnumBasedAnimatorWindow)GetWindow(typeof(EnumBasedAnimatorWindow), true);
window.Show();
}
}
namespace {0}
{{
public enum Float
{{
{1}
}}
}}
using UnityEngine;
public static class MetaGenUtility
{
const string relativeTemplatePath = "/"; // template files path relative to the Assets folder
const string relativeGeneratePath = "/"; // where should we generate the new scripts relative to the Assets folder
public static string templatePath => Application.dataPath + relativeTemplatePath;
public static string generatePath => Application.dataPath + relativeGeneratePath;
}
using System.Collections.Generic;
using System;
[Serializable] public class Dictionary_{0}_{1} : Dictionary<{0}, {1}>
{{
}}
using UnityEngine;
using UnityEditor;
using System.IO;
public class NonGenericDictionaryWindow : EditorWindow
{
const string windowName = "Non Generic Dictionary Generator";
string keyType;
string valueType;
void OnGUI()
{
keyType = EditorGUILayout.TextField("Key Type Name", keyType);
valueType = EditorGUILayout.TextField("Value Type Name", valueType);
if (GUILayout.Button("Generate"))
GenerateDico();
}
void GenerateDico()
{
string template = File.ReadAllText(MetaGenUtility.templatePath + "NonGenericDictionary.txt");
string scriptText = string.Format(template, keyType, valueType);
File.WriteAllText(MetaGenUtility.generatePath + $"Dictionary_{keyType}_{valueType}.cs", scriptText);
}
void Awake()
{
titleContent = new GUIContent(windowName);
}
void OnDestroy()
{
AssetDatabase.Refresh();
}
[MenuItem("Juste Tools/" + windowName)]
static void Init()
{
NonGenericDictionaryWindow window = (NonGenericDictionaryWindow)GetWindow(typeof(NonGenericDictionaryWindow), true);
window.Show();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment