public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(position, label, property); if (property.propertyType == SerializedPropertyType.ManagedReference) { TypePopupCache popup = GetTypePopup(property); // Draw the subclass selector popup. Rect popupPosition = new Rect(position); popupPosition.width -= EditorGUIUtility.labelWidth; popupPosition.x += EditorGUIUtility.labelWidth; popupPosition.height = EditorGUIUtility.singleLineHeight; if (EditorGUI.DropdownButton(popupPosition, new GUIContent(GetTypeName(property)), FocusType.Keyboard)) { m_TargetProperty = property; popup.TypePopup.Show(popupPosition); } // Draw the managed reference property. EditorGUI.PropertyField(position, property, label, true); } else { EditorGUI.LabelField(position, label, k_IsNotManagedReferenceLabel); } EditorGUI.EndProperty(); }
TypePopupCache GetTypePopup(SerializedProperty property) { // Cache this string. This property internally call Assembly.GetName, which result in a large allocation. string managedReferenceFieldTypename = property.managedReferenceFieldTypename; if (!m_TypePopups.TryGetValue(managedReferenceFieldTypename, out TypePopupCache result)) { var state = new AdvancedDropdownState(); Type baseType = ManagedReferenceUtility.GetType(managedReferenceFieldTypename); var popup = new AdvancedTypePopup( TypeCache.GetTypesDerivedFrom(baseType).Append(baseType).Where(p => (p.IsPublic || p.IsNestedPublic) && !p.IsAbstract && !p.IsGenericType && !k_UnityObjectType.IsAssignableFrom(p) && Attribute.IsDefined(p, typeof(SerializableAttribute)) ), k_MaxTypePopupLineCount, state ); popup.OnItemSelected += item => { Type type = item.Type; object obj = m_TargetProperty.SetManagedReference(type); m_TargetProperty.isExpanded = (obj != null); m_TargetProperty.serializedObject.ApplyModifiedProperties(); m_TargetProperty.serializedObject.Update(); }; result = new TypePopupCache(popup, state); m_TypePopups.Add(managedReferenceFieldTypename, result); } return(result); }