/
DropdownSubtypesDrawer.cs
76 lines (58 loc) · 2.22 KB
/
DropdownSubtypesDrawer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
using UnityEditor;
using UnityEngine;
using System;
using System.Linq;
using System.Collections.Generic;
// draws a dropdown containing all subtypes
// of the base type contained in DropdownSubtypesOf.
[CustomPropertyDrawer (typeof (DropdownSubtypesOf))]
public class DropdownSubtypesDrawer : PropertyDrawer
{
public static IEnumerable<System.Type> FindSubclassesOf(System.Type t)
{
var subclasses = new List<System.Type>();
foreach(var asm in System.AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var type in asm.GetTypes())
{
if (type.IsAbstract == false && t.IsAssignableFrom(type))
{
subclasses.Add(type);
}
}
}
return subclasses;
}
public override void OnGUI (Rect position,
SerializedProperty prop,
GUIContent label)
{
if(prop.propertyType != SerializedPropertyType.String)
{
throw new UnityException("property " + prop
+ " must be string to use with DropdownSubtypesOf");
}
var popupRect = EditorGUI.PrefixLabel(position,
GUIUtility.GetControlID(FocusType.Passive),
label);
var baseType = SubtypesAttribute.BaseType;
var subclasses = FindSubclassesOf(baseType).Select(t => t.Name).ToArray();
var currentClassName = prop.stringValue;
var currentClassIndex = subclasses.Length - 1;
for(; currentClassIndex >= 0; --currentClassIndex)
{
if (subclasses[currentClassIndex] == currentClassName)
{
break;
}
}
int newClassIndex = EditorGUI.Popup(popupRect, currentClassIndex, subclasses);
prop.stringValue = newClassIndex < 0 ? "" : subclasses[newClassIndex];
}
//////////////////////////////////////////////////
private DropdownSubtypesOf SubtypesAttribute
{
get { return attribute as DropdownSubtypesOf; }
}
//////////////////////////////////////////////////
}