Created
March 28, 2022 14:09
-
-
Save chadefranklin/cd2e6c4d89928ce25274395ff8690f9a to your computer and use it in GitHub Desktop.
An unfinished Custom Property Drawer used to select multiple implementations of an interface.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SelectImplementationAttribute : PropertyAttribute | |
{ | |
public Type FieldType; | |
public SelectImplementationAttribute() | |
{ | |
} | |
public SelectImplementationAttribute(Type fieldType) | |
{ | |
FieldType = fieldType; | |
} | |
} | |
[CustomPropertyDrawer(typeof(SelectImplementationAttribute))] | |
public class SelectImplementationDrawer : PropertyDrawer | |
{ | |
private Type[] _implementations; | |
private int _implementationTypeIndex = -1; | |
private Type type; | |
public override bool CanCacheInspectorGUI(SerializedProperty property) | |
{ | |
return true; | |
} | |
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |
{ | |
//EditorGUI.BeginProperty(position, label, property); | |
position.height = EditorGUIUtility.singleLineHeight; | |
if (_implementations == null) | |
{ | |
Debug.Log("implementations null"); | |
_implementationTypeIndex = -1; | |
type = (attribute as SelectImplementationAttribute).FieldType ?? fieldInfo.FieldType; | |
if (type.HasElementType) | |
{ | |
type = type.GetElementType(); | |
} | |
_implementations = GetImplementations(type).Where(impl => !impl.IsSubclassOf(typeof(UnityEngine.Object))).ToArray(); | |
} | |
string implementationName = property.managedReferenceFullTypename.Split('.').Last(); | |
for (int i = 0; i < _implementations.Length; i++) | |
{ | |
if (implementationName == _implementations[i].Name) | |
{ | |
_implementationTypeIndex = i; | |
break; | |
} | |
} | |
EditorGUI.BeginChangeCheck(); | |
_implementationTypeIndex = EditorGUI.Popup(position, type.FullName + " Implementation", _implementationTypeIndex, _implementations.Select(impl => impl.FullName).ToArray()); | |
if (EditorGUI.EndChangeCheck()) | |
{ | |
object instance = Activator.CreateInstance(_implementations[_implementationTypeIndex]); | |
property.managedReferenceValue = instance; | |
} | |
position.y += EditorGUIUtility.singleLineHeight; | |
EditorGUI.PropertyField(position, property, true); | |
//EditorGUI.EndProperty(); | |
} | |
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | |
{ | |
return EditorGUI.GetPropertyHeight(property) + EditorGUIUtility.singleLineHeight; | |
} | |
public static Type[] GetImplementations(Type interfaceType) | |
{ | |
var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes()); | |
return types.Where(p => interfaceType.IsAssignableFrom(p) && !p.IsAbstract && !p.IsEnum && !p.IsGenericTypeDefinition && !p.IsInterface && !p.IsPrimitive && !p.IsSpecialName).ToArray(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment