/// <summary> /// Equality operator. /// </summary> public override bool Equals(object obj) { if (obj == null) { return(!isValid); } if (obj is PropertyBindingReference) { PropertyBindingReference pb = obj as PropertyBindingReference; return(mTarget == pb.mTarget && string.Equals(mName, pb.mName)); } return(false); }
/// <summary> /// Draw the actual property. /// </summary> public override void OnGUI(Rect rect, SerializedProperty prop, GUIContent label) { SerializedProperty target = prop.FindPropertyRelative("mTarget"); SerializedProperty field = prop.FindPropertyRelative("mName"); rect.height = 16f; EditorGUI.PropertyField(rect, target, label); Component comp = target.objectReferenceValue as Component; if (comp != null) { rect.y += 18f; GUI.changed = false; EditorGUI.BeginDisabledGroup(target.hasMultipleDifferentValues); int index = 0; // Get all the properties on the target game object List <ComponentReference> list = GetProperties(comp.gameObject, mustRead, mustWrite); // We want the field to look like "Component.property" rather than just "property" string current = PropertyBindingReference.ToString(target.objectReferenceValue as Component, field.stringValue); // Convert all the properties to names string[] names = GetNames(list, current, out index); // Draw a selection list GUI.changed = false; rect.xMin += EditorGUIUtility.labelWidth; rect.width -= 18f; int choice = EditorGUI.Popup(rect, "", index, names); // Update the target object and property name if (GUI.changed && choice > 0) { ComponentReference ent = list[choice - 1]; target.objectReferenceValue = ent.target; field.stringValue = ent.name; } EditorGUI.EndDisabledGroup(); } }
/// <summary> /// Collect a list of usable properties and fields. /// </summary> public static List <ComponentReference> GetProperties(GameObject target, bool read, bool write) { Component[] comps = target.GetComponents <Component>(); List <ComponentReference> list = new List <ComponentReference>(); for (int i = 0, imax = comps.Length; i < imax; ++i) { Component comp = comps[i]; if (comp == null) { continue; } Type type = comp.GetType(); BindingFlags flags = BindingFlags.Instance | BindingFlags.Public; FieldInfo[] fields = type.GetFields(flags); PropertyInfo[] props = type.GetProperties(flags); // The component itself without any method if (PropertyBindingReference.Convert(comp, filter)) { ComponentReference ent = new ComponentReference(); ent.target = comp; list.Add(ent); } for (int b = 0; b < fields.Length; ++b) { FieldInfo field = fields[b]; if (filter != typeof(void)) { if (canConvert) { if (!PropertyBindingReference.Convert(field.FieldType, filter)) { continue; } } else if (!filter.IsAssignableFrom(field.FieldType)) { continue; } } ComponentReference ent = new ComponentReference(); ent.target = comp; ent.name = field.Name; list.Add(ent); } for (int b = 0; b < props.Length; ++b) { PropertyInfo prop = props[b]; if (read && !prop.CanRead) { continue; } if (write && !prop.CanWrite) { continue; } if (filter != typeof(void)) { if (canConvert) { if (!PropertyBindingReference.Convert(prop.PropertyType, filter)) { continue; } } else if (!filter.IsAssignableFrom(prop.PropertyType)) { continue; } } ComponentReference ent = new ComponentReference(); ent.target = comp; ent.name = prop.Name; list.Add(ent); } } return(list); }