Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using UnityEngine.Events;
- using UnityEngine;
- using Utils;
- using UnityEditor.UIElements;
- using UnityEditor;
- using UnityEngine.UIElements;
- using UnityEditor.PackageManager.UI;
- using UnityEditor.Rendering;
- using UnityEditor.Experimental.GraphView;
- using System.Reflection;
- namespace Utils
- {
- [Serializable]
- public class ActiveField<T>
- {
- [SerializeField] private T _value;
- public UnityEvent Changed;
- public T Value
- {
- get => _value;
- set
- {
- _value = value;
- Changed?.Invoke();
- }
- }
- public void SetValue(T value) => Value = value;
- public ActiveField(T value, UnityEvent changed)
- {
- Changed = changed;
- _value = value;
- }
- }
- [CustomPropertyDrawer(typeof(ActiveField<>))]
- public class ActiveFieldDrawer : PropertyDrawer
- {
- public override VisualElement CreatePropertyGUI(SerializedProperty property)
- {
- var serialized_changed_event_property = property.FindPropertyRelative("Changed");
- var changed_event = PropertyReflectionGetter.SerializedPropertyToObject<UnityEvent>(serialized_changed_event_property);
- var container = new VisualElement();
- var changed_event_field = new PropertyField(serialized_changed_event_property);
- var value_field = new PropertyField(property.FindPropertyRelative("_value"));
- value_field.RegisterValueChangeCallback((_) => changed_event?.Invoke());
- container.Add(new Label($"ActiveEvent<>: [{property.displayName}]"));
- container.Add(value_field);
- container.Add(changed_event_field);
- return container;
- }
- }
- public static class PropertyReflectionGetter
- {
- public static T SerializedPropertyToObject<T>(SerializedProperty property)
- {
- return GetNestedObject<T>(property.propertyPath, GetSerializedPropertyRootComponent(property), true); //The "true" means we will also check all base classes
- }
- public static Component GetSerializedPropertyRootComponent(SerializedProperty property)
- {
- return (Component)property.serializedObject.targetObject;
- }
- public static T GetNestedObject<T>(string path, object obj, bool includeAllBases = false)
- {
- foreach (string part in path.Split('.'))
- {
- obj = GetFieldOrPropertyValue<object>(part, obj, includeAllBases);
- }
- return (T)obj;
- }
- public static T GetFieldOrPropertyValue<T>(string fieldName, object obj, bool includeAllBases = false, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
- {
- FieldInfo field = obj.GetType().GetField(fieldName, bindings);
- if (field != null) return (T)field.GetValue(obj);
- PropertyInfo property = obj.GetType().GetProperty(fieldName, bindings);
- if (property != null) return (T)property.GetValue(obj, null);
- if (includeAllBases)
- {
- foreach (Type type in GetBaseClassesAndInterfaces(obj.GetType()))
- {
- field = type.GetField(fieldName, bindings);
- if (field != null) return (T)field.GetValue(obj);
- property = type.GetProperty(fieldName, bindings);
- if (property != null) return (T)property.GetValue(obj, null);
- }
- }
- return default(T);
- }
- public static void SetFieldOrPropertyValue<T>(string fieldName, object obj, object value, bool includeAllBases = false, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
- {
- FieldInfo field = obj.GetType().GetField(fieldName, bindings);
- if (field != null)
- {
- field.SetValue(obj, value);
- return;
- }
- PropertyInfo property = obj.GetType().GetProperty(fieldName, bindings);
- if (property != null)
- {
- property.SetValue(obj, value, null);
- return;
- }
- if (includeAllBases)
- {
- foreach (Type type in GetBaseClassesAndInterfaces(obj.GetType()))
- {
- field = type.GetField(fieldName, bindings);
- if (field != null)
- {
- field.SetValue(obj, value);
- return;
- }
- property = type.GetProperty(fieldName, bindings);
- if (property != null)
- {
- property.SetValue(obj, value, null);
- return;
- }
- }
- }
- }
- public static IEnumerable<Type> GetBaseClassesAndInterfaces(this Type type, bool includeSelf = false)
- {
- List<Type> allTypes = new List<Type>();
- if (includeSelf) allTypes.Add(type);
- if (type.BaseType == typeof(object))
- {
- allTypes.AddRange(type.GetInterfaces());
- }
- else
- {
- allTypes.AddRange(
- Enumerable
- .Repeat(type.BaseType, 1)
- .Concat(type.GetInterfaces())
- .Concat(type.BaseType.GetBaseClassesAndInterfaces())
- .Distinct());
- //I found this on stackoverflow
- }
- return allTypes;
- }
- }
- /*
- [CustomPropertyDrawer(typeof(ActiveField<float>))]
- public class ActiveFieldEditor : PropertyDrawer
- {
- public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
- {
- return base.GetPropertyHeight(property, label) * 3;
- }
- public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
- {
- var freeRect = EditorGUI.PrefixLabel(position, new GUIContent($"He-he"));
- base.OnGUI(position, property, label);
- */
- /*
- using (var scope = new EditorGUI.PropertyScope(position, label, property))
- {
- var freeRect = EditorGUI.PrefixLabel(position, new GUIContent($"He-he"));
- }
- */
- /*
- var minLimit = property.FindPropertyRelative("minLimit");
- var maxLimit = property.FindPropertyRelative("maxLimit");
- var minValue = property.FindPropertyRelative("minValue");
- var maxValue = property.FindPropertyRelative("maxValue");
- using (var scope = new EditorGUI.PropertyScope(position, label, property))
- {
- var freeRect = EditorGUI.PrefixLabel(position, new GUIContent($"{minLimit.floatValue}|{maxLimit.floatValue}"));
- var lineSize = freeRect.height / 3;
- EditorGUI.BeginChangeCheck();
- var minValueFloat = minValue.floatValue;
- var maxValueFloat = maxValue.floatValue;
- var sliderRect = new Rect(freeRect.x, freeRect.y, freeRect.width, lineSize);
- EditorGUI.MinMaxSlider(sliderRect, ref minValueFloat, ref maxValueFloat, minLimit.floatValue, maxLimit.floatValue);
- var minLimitRect = new Rect(freeRect.x, freeRect.y + 1 * lineSize, freeRect.width, lineSize);
- var maxLimitRect = new Rect(freeRect.x, freeRect.y + 2 * lineSize, freeRect.width, lineSize);
- var minLimitFloat = EditorGUI.FloatField(new Rect(minLimitRect), "Min limit", minLimit.floatValue);
- var maxLimitFloat = EditorGUI.FloatField(new Rect(maxLimitRect), "Max limit", maxLimit.floatValue);
- if (EditorGUI.EndChangeCheck())
- {
- minLimit.floatValue = minLimitFloat;
- maxLimit.floatValue = maxLimitFloat;
- minValue.floatValue = minValueFloat;
- maxValue.floatValue = maxValueFloat;
- }
- }
- */
- /*}
- }*/
- // [CustomEditor(typeof(ActiveField<>))]
- // class GenericActiveFieldEditor : Editor
- // {
- // public override void OnInspectorGUI()
- // {
- // EditorGUILayout.LabelField("I'm shown OK generic");
- // }
- // }
- // [CustomEditor(typeof(ActiveField<float>))]
- // class FloatActiveFieldEditor: Editor
- // {
- // public override void OnInspectorGUI()
- // {
- // EditorGUILayout.LabelField("I'm shown OK float");
- // }
- // }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement