//Will expose a property REGARDLESS OF ITS ATTRIBUTES public static void ExposeProperty(this Editor me, PropertyInfo info) { if (!info.CanRead) { throw new Exception("An exposed property must at least have a getter."); } if (!info.CanWrite) { GUI.enabled = false; } SerializedPropertyType type = GetSerializedPropertyTypeFromType(info.PropertyType); var name = AddSpacesBeforeCapitals(info.Name); switch (type) { case SerializedPropertyType.Integer: { var getter = me.target.GetPropertyGetter<object, int>(info); int val = EditorGUILayout.IntField(name, getter()); if (info.CanWrite) { var setter = me.target.GetPropertySetter<object, int>(info); setter(val); } } break; case SerializedPropertyType.Boolean: { var getter = me.target.GetPropertyGetter<object, bool>(info); bool val = EditorGUILayout.Toggle(name, getter()); if (info.CanWrite) { var setter = me.target.GetPropertySetter<object, bool>(info); setter(val); } } break; case SerializedPropertyType.Float: { var getter = me.target.GetPropertyGetter<object, float>(info); float val = EditorGUILayout.FloatField(name, getter()); if (info.CanWrite) { var setter = me.target.GetPropertySetter<object, float>(info); setter(val); } } break; case SerializedPropertyType.String: { var getter = me.target.GetPropertyGetter<object, string>(info); string val = EditorGUILayout.TextField(name, getter()); if (info.CanWrite) { var setter = me.target.GetPropertySetter<object, string>(info); setter(val); } } break; case SerializedPropertyType.Color: { var getter = me.target.GetPropertyGetter<object, Color>(info); Color val = EditorGUILayout.ColorField(name, getter()); if (info.CanWrite) { var setter = me.target.GetPropertySetter<object, Color>(info); setter(val); } } break; case SerializedPropertyType.ObjectReference: { var getter = me.target.GetPropertyGetter<object, UnityEngine.Object>(info); UnityEngine.Object val = getter(); var drawerType = CustomInspectorScripts.GetDrawerTypeForType(info.PropertyType); if (drawerType == null) { val = EditorGUILayout.ObjectField(name, getter(), info.PropertyType, true); } else { PropertyDrawer drawer = drawerType.GetConstructor(EmptyTypeArray).Invoke(EmptyObjectArray) as PropertyDrawer; SerializedPropertyWrapper obj = ScriptableObject.CreateInstance<SerializedPropertyWrapper>(); obj.StoredObject = val; var editor = Editor.CreateEditor(obj); var iter = editor.serializedObject.GetIterator(); iter.NextVisible(true);//Go past Base iter.NextVisible(true);//Go past m_script var content = new GUIContent(); content.text = name; GUILayout.Label(""); var pos = GUILayoutUtility.GetLastRect(); drawer.OnGUI(pos, iter, content); val = iter.objectReferenceValue; } if (info.CanWrite) { //Must use a dynamic function call for this one. Otherwise I would have to check with all the different object types in Unity. info.SetValue(me.target, val, EmptyObjectArray); } } break; case SerializedPropertyType.LayerMask: { var getter = me.target.GetPropertyGetter<object, LayerMask>(info); LayerMask val = EditorGUILayout.LayerField(name, getter()); if (info.CanWrite) { var setter = me.target.GetPropertySetter<object, LayerMask>(info); setter(val); } } break; case SerializedPropertyType.Enum: { Enum val = (Enum)info.GetGetMethod().Invoke(me.target, EmptyObjectArray); val = EditorGUILayout.EnumPopup(name, val); if (info.CanWrite) { info.SetValue(me.target, val, EmptyObjectArray); } } break; case SerializedPropertyType.Vector2: { var getter = me.target.GetPropertyGetter<object, Vector2>(info); Vector2 val = EditorGUILayout.Vector2Field(name, getter()); if (info.CanWrite) { var setter = me.target.GetPropertySetter<object, Vector2>(info); setter(val); } } break; case SerializedPropertyType.Vector3: { var getter = me.target.GetPropertyGetter<object, Vector3>(info); Vector3 val = EditorGUILayout.Vector3Field(name, getter()); if (info.CanWrite) { var setter = me.target.GetPropertySetter<object, Vector3>(info); setter(val); } } break; case SerializedPropertyType.Vector4: { var getter = me.target.GetPropertyGetter<object, Vector4>(info); Vector4 val = EditorGUILayout.Vector4Field(name, getter()); if (info.CanWrite) { var setter = me.target.GetPropertySetter<object, Vector4>(info); setter(val); } } break; //case SerializedPropertyType.ArraySize: //{ // //Will work out later. Will need to be recursive most likely. // //var getter = me.target.GetPropertyGetter<object, Vector4>(info); // //Vector4 val = EditorGUILayout.(name, getter()); // //if (info.CanWrite) // //{ // // var setter = me.target.GetPropertySetter<object, Vector4>(info); // // setter(val); // //} //} //break; case SerializedPropertyType.AnimationCurve: { var getter = me.target.GetPropertyGetter<object, AnimationCurve>(info); AnimationCurve val = EditorGUILayout.CurveField(name, getter()); if (info.CanWrite) { var setter = me.target.GetPropertySetter<object, AnimationCurve>(info); setter(val); } } break; case SerializedPropertyType.Bounds: { var getter = me.target.GetPropertyGetter<object, Bounds>(info); Bounds val = EditorGUILayout.BoundsField(name, getter()); if (info.CanWrite) { var setter = me.target.GetPropertySetter<object, Bounds>(info); setter(val); } } break; //case SerializedPropertyType.Gradient: //{ // //Will work out later // //var getter = me.target.GetPropertyGetter<object, Gradient>(info); // //Gradient val = EditorGUILayout.(name, getter()); // //if (info.CanWrite) // //{ // // var setter = me.target.GetPropertySetter<object, Gradient>(info); // // setter(val); // //} //} //break; case SerializedPropertyType.Quaternion: { var getter = me.target.GetPropertyGetter<object, Quaternion>(info); Quaternion val = new Quaternion(); val.FromVector4(EditorGUILayout.Vector4Field(name, getter().ToVector4())); if (info.CanWrite) { var setter = me.target.GetPropertySetter<object, Quaternion>(info); setter(val); } } break; //The draw function for the type must be exposed using the ExposeDrawFunction attribute. case SerializedPropertyType.Generic: default: { var propType = info.PropertyType; if (TypeDrawFunctions.ContainsKey(propType)) { var rect = EditorGUILayout.GetControlRect(); var val = info.GetGetMethod().Invoke(me.target, EmptyObjectArray); var contentName = new GUIContent(); contentName.text = name; val = TypeDrawFunctions[propType](rect, val, contentName, info); if (info.CanWrite) { if(!propType.IsValueType) { info.SetValue(me.target, val, EmptyObjectArray); } else { info.SetValue(me.target, ((ReferenceType)val).GetValue(), EmptyObjectArray); } } } } break; } GUI.enabled = true; }