Skip to content

Instantly share code, notes, and snippets.

@chadefranklin
Created March 28, 2022 14:09
Show Gist options
  • Save chadefranklin/cd2e6c4d89928ce25274395ff8690f9a to your computer and use it in GitHub Desktop.
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.
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