- Home /
Generic CustomEditor
This question borders several previous questions so to be clear: It is not a matter of serialization of generic types, which has been answered elsewhere.
I have a generic class:
public class EnumeratedPalette<T> : AbstractPalette where T : System.IConvertible
{
Color[] colors;
public static int EnumLength {
get {
return System.Enum.GetValues (typeof(T)).Length;
}
}
public static string FieldLabel(int index) {
return System.Enum.GetName (typeof(T), index);
}
protected void Reset()
{
colors = new Color[EnumLength];
}
}
And then I make specific versions of it like this:
public enum FaceColors { Skin, Eye, Hair };
public class FacePalette : ProcPixel.Fundamentals.EnumeratedPalette<FaceColors> { };
They serialize perfectly and work in unity as expected, getting the right length on colors
when added to an GameObject
. But instead of having a colors
be a simple list in the inspector, I would want a generic CustomEditor
for EnumeratedPalette
so that I can set nice labels on the property-drawers based on the specific enum
( Color
is a struct of mine with its own CustomPropertyDrawer
which draws whatever label sent to it):
[CustomEditor(typeof(EnumeratedPalette<>), true)]
public class EnumeratedPaletteEditor<T> : Editor where T: System.IConvertible
{
public override void OnInspectorGUI ()
{
int size = EnumeratedPalette<T>.EnumLength;
for (int index = 0; index < size; index++) {
EditorGUILayout.PropertyField (serializedObject.FindProperty ("colors").GetArrayElementAtIndex (index), new GUIContent(EnumeratedPalette<T>.FieldLabel (index)));
}
}
}
Edit / Workaround solution
I made a generic helper class:
public static class EnumEditorHelper<T> where T: System.IConvertible
{
public static void UnpackProperty(SerializedProperty prop)
{
int size = EnumeratedPalette<T>.EnumLength;
for (int index = 0; index < size; index++) {
EditorGUILayout.PropertyField (prop.GetArrayElementAtIndex (index), new GUIContent(EnumeratedPalette<T>.FieldLabel (index)));
}
}
}
And then each CustomEditor
can look like:
[CustomEditor(typeof(FacePalette), false)]
public class FacePaletteEditor : Editor {
public override void OnInspectorGUI ()
{
EditorGUI.indentLevel += 1;
EnumEditorHelper<FaceColors>.UnpackProperty(serializedObject.FindProperty("colors"));
EditorGUI.indentLevel -= 1;
serializedObject.ApplyModifiedProperties ();
}
}
Answer by Bunny83 · Jan 25, 2016 at 05:05 AM
The Editor class is derived from ScriptableObject and as such it can't be a generic type. You need a concrete class and the class name has to match the filename.
You could have a generic base class like this but the actual editors must not contain a generic parameter. The editor instance has to be serializable as well ^^. Unity serializes all editors and editorwindows (which are also ScriptableObjects) whenever you change playmode or scripts are recompiled.
Even if Unity would support generic types, how should Unity decide which type it should use as generic parameter for your class when it creates an editor instance? The type of the inspected object? That would be "FacePalette" in your case.
What is "AbstractPalette" actually derived from? I guess, due to the "Reset" method, it's a MonoBehaviour? The generic parameter on your "EnumeratedPalette" class might still make problems when it comes to the editor. A generic base class makes it difficult to treat an instance as "base class" when you don't know the generic parameter type.
One solution might be to go another step back and insert a non generic base class infront of the generic which implements the "EnumLength" property and FieldLabel as virtual instance members. The generic class can override those. Inside the editor you can treat all instances as the non generic baseclass so you can use the method / property without knowing the concrete type inside the editor.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Custom property drawer for generic 0 Answers
[solved]Using WWW instead of resources.load causes hang 1 Answer
When do the Attributes get set? 1 Answer