public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // Rely on the default inspector GUI EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(position, property, label); // // Update only when necessary SetPropertyAttribute setProperty = attribute as SetPropertyAttribute; // if (EditorGUI.EndChangeCheck()) // { // // When a SerializedProperty is modified the actual field does not have the current value set (i.e. // // FieldInfo.GetValue() will return the prior value that was set) until after this OnGUI call has completed. // // Therefore, we need to mark this property as dirty, so that it can be updated with a subsequent OnGUI event // // (e.g. Repaint) // object parent = GetParentObjectOfProperty(property.propertyPath, property.serializedObject.targetObject); // Type type = parent.GetType(); // PropertyInfo pi = pi = type.GetProperty(setProperty.Name); // fieldInfo.SetValue(parent,pi.GetValue(parent)); // setProperty.IsDirty = true; // } // else if (setProperty.IsDirty) // { // // The propertyPath may reference something that is a child field of a field on this Object, so it is necessary // // to find which object is the actual parent before attempting to set the property with the current value. // object parent = GetParentObjectOfProperty(property.propertyPath, property.serializedObject.targetObject); // Type type = parent.GetType(); // PropertyInfo pi = pi = type.GetProperty(setProperty.Name); // if (pi == null) // { // Debug.LogError("Invalid property name: " + setProperty.Name + "\nCheck your [SetProperty] attribute"); // } // else // { // // Use FieldInfo instead of the SerializedProperty accessors as we'd have to deal with every // // SerializedPropertyType and use the correct accessor // pi.SetValue(parent, fieldInfo.GetValue(parent), null); // } // setProperty.IsDirty = false; // } object parent = GetParentObjectOfProperty(property.propertyPath, property.serializedObject.targetObject); Type type = parent.GetType(); PropertyInfo pi = pi = type.GetProperty(setProperty.Name); if (pi == null) { Debug.LogError("Invalid property name: " + setProperty.Name + "\nCheck your [SetProperty] attribute"); } else { // Use FieldInfo instead of the SerializedProperty accessors as we'd have to deal with every // SerializedPropertyType and use the correct accessor pi.SetValue(parent, fieldInfo.GetValue(parent), null); } setProperty.IsDirty = false; }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(position, property, label); if (EditorGUI.EndChangeCheck()) { SetPropertyAttribute setPropertyAttribute = attribute as SetPropertyAttribute; property.serializedObject.ApplyModifiedProperties(); object targetObj = property.serializedObject.targetObject; Type targetObjType = targetObj.GetType(); if (propertyInfo == null) { propertyInfo = GetPropertyInfo(setPropertyAttribute, property, targetObjType); } if (propertyInfo == null) { Debug.LogError("Invalid property name: " + setPropertyAttribute.GetPropertyName() + "\nCheck your [SetProperty] attribute"); } else { propertyInfo.SetValue(targetObj, fieldInfo.GetValue(targetObj), null); } } }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // Rely on the default inspector GUI EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(position, property, label, true); // Update only when necessary SetPropertyAttribute setProperty = attribute as SetPropertyAttribute; if (EditorGUI.EndChangeCheck()) { // When a SerializedProperty is modified the actual field does not have the current value set (i.e. // FieldInfo.GetValue() will return the prior value that was set) until after this OnGUI call has completed. // Therefore, we need to mark this property as dirty, so that it can be updated with a subsequent OnGUI event // (e.g. Repaint) setProperty.IsDirty = true; // In arrays/lists, the property that has changed is not necessarily the one that causes the update OnGUI event. // Therefore, we will also store a reference to the changed property. setProperty.Property = property; } else if (setProperty.IsDirty) { // The user might have selected more than one object, so we need to make sure the property gets updated properly on all of these. foreach (UnityEngine.Object obj in setProperty.Property.serializedObject.targetObjects) { // The propertyPath may reference something that is a child field of a field on this Object, so it is necessary // to find which object is the actual parent before attempting to set the property with the current value. object parent = GetParentObjectOfProperty(setProperty.Property.propertyPath, obj); Type type = parent.GetType(); PropertyInfo pi = type.GetProperty(setProperty.Name); Type propertyType = pi.PropertyType; Type fieldType = fieldInfo.FieldType; if (pi == null) { Debug.LogError("Invalid property name: " + setProperty.Name + " @" + setProperty.Property.propertyPath + "\nCheck your [SetProperty] attribute"); } else if (propertyType != fieldType) { Debug.LogError("Invalid property type " + propertyType.ToString() + " @" + setProperty.Property.propertyPath + "\nProperty must be of same type as source Field type " + fieldType.ToString()); } else { // Using FieldInfo instead of the SerializedProperty accessors causes our property to be updated incorrectly, unless it's the last element of a collection. // Therefore we need to deal with the SerializedProperty accessors here. object propValue = GetSerializedPropertyValue(setProperty.Property, propertyType); pi.SetValue(parent, propValue, null); } } setProperty.IsDirty = false; setProperty.Property = null; } }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { object targetObj = property.serializedObject.targetObject; object oldValue = fieldInfo.GetValue(targetObj); SetPropertyAttribute setPropertyAttribute = attribute as SetPropertyAttribute; EditorGUI.BeginChangeCheck(); if (setPropertyAttribute.NeedDrawRange) { if (property.propertyType == SerializedPropertyType.Float) { EditorGUI.Slider(position, property, setPropertyAttribute.MinValue, setPropertyAttribute.MaxValue, label); } else if (property.propertyType == SerializedPropertyType.Integer) { EditorGUI.IntSlider(position, property, (int)setPropertyAttribute.MinValue, (int)setPropertyAttribute.MaxValue, label); } } else { EditorGUI.PropertyField(position, property, label); } // Change property value if (EditorGUI.EndChangeCheck()) { property.serializedObject.ApplyModifiedProperties(); Type targetObjType = targetObj.GetType(); if (propertyInfo == null) { propertyInfo = GetPropertyInfo(setPropertyAttribute, property, targetObjType); //Check property if (propertyInfo == null) { Debug.LogError("Invalid property name: " + setPropertyAttribute.PropertyName + "\nCheck your [SetProperty] attribute"); } } else { Debug.Log(oldValue); object newValue = fieldInfo.GetValue(targetObj); Debug.Log(newValue); fieldInfo.SetValue(targetObj, oldValue); propertyInfo.SetValue(targetObj, newValue, null); } } }
private PropertyInfo GetPropertyInfo(SetPropertyAttribute setPropertyAttribute, SerializedProperty property, Type type) { PropertyInfo propertyInfo; string propertyName = null; if (setPropertyAttribute.GetPropertyName() != null) { propertyName = setPropertyAttribute.GetPropertyName(); } else { char[] chars = property.name.ToCharArray(); chars[0] = char.ToUpper(chars[0]); propertyName = new string(chars); } propertyInfo = type.GetProperty(propertyName); return(propertyInfo); }
private PropertyInfo GetPropertyInfo(SetPropertyAttribute setPropertyAttribute, SerializedProperty property, Type type) { PropertyInfo propertyInfo; //Obtaining property names based on parameters string propertyName = null; if (!string.IsNullOrEmpty(setPropertyAttribute.PropertyName)) { propertyName = setPropertyAttribute.PropertyName; } else { char[] chars = property.name.ToCharArray(); chars[0] = char.ToUpper(chars[0]); propertyName = new string(chars); } //Get property propertyInfo = type.GetProperty(propertyName); return(propertyInfo); }