Advertisement
Ilya_Bykonya

Untitled

Mar 14th, 2024
572
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.78 KB | Source Code | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using UnityEngine.Events;
  7. using UnityEngine;
  8. using Utils;
  9. using UnityEditor.UIElements;
  10. using UnityEditor;
  11. using UnityEngine.UIElements;
  12. using UnityEditor.PackageManager.UI;
  13. using UnityEditor.Rendering;
  14. using UnityEditor.Experimental.GraphView;
  15. using System.Reflection;
  16.  
  17. namespace Utils
  18. {
  19.     [Serializable]
  20.     public class ActiveField<T>
  21.     {
  22.         [SerializeField] private T _value;
  23.         public UnityEvent Changed;
  24.  
  25.         public T Value
  26.         {
  27.             get => _value;
  28.             set
  29.             {
  30.                 _value = value;
  31.                 Changed?.Invoke();
  32.             }
  33.         }
  34.  
  35.         public void SetValue(T value) => Value = value;
  36.         public ActiveField(T value, UnityEvent changed)
  37.         {
  38.             Changed = changed;
  39.             _value = value;
  40.         }
  41.     }
  42.  
  43.  
  44.    
  45.     [CustomPropertyDrawer(typeof(ActiveField<>))]
  46.     public class ActiveFieldDrawer : PropertyDrawer
  47.     {
  48.         public override VisualElement CreatePropertyGUI(SerializedProperty property)
  49.         {
  50.             var serialized_changed_event_property = property.FindPropertyRelative("Changed");
  51.             var changed_event = PropertyReflectionGetter.SerializedPropertyToObject<UnityEvent>(serialized_changed_event_property);
  52.  
  53.             var container = new VisualElement();
  54.             var changed_event_field = new PropertyField(serialized_changed_event_property);
  55.             var value_field = new PropertyField(property.FindPropertyRelative("_value"));
  56.  
  57.             value_field.RegisterValueChangeCallback((_) => changed_event?.Invoke());
  58.             container.Add(new Label($"ActiveEvent<>: [{property.displayName}]"));
  59.             container.Add(value_field);
  60.             container.Add(changed_event_field);
  61.             return container;
  62.         }
  63.     }
  64.     public static class PropertyReflectionGetter
  65.     {
  66.         public static T SerializedPropertyToObject<T>(SerializedProperty property)
  67.         {
  68.             return GetNestedObject<T>(property.propertyPath, GetSerializedPropertyRootComponent(property), true); //The "true" means we will also check all base classes
  69.         }
  70.         public static Component GetSerializedPropertyRootComponent(SerializedProperty property)
  71.         {
  72.             return (Component)property.serializedObject.targetObject;
  73.         }
  74.         public static T GetNestedObject<T>(string path, object obj, bool includeAllBases = false)
  75.         {
  76.             foreach (string part in path.Split('.'))
  77.             {
  78.                 obj = GetFieldOrPropertyValue<object>(part, obj, includeAllBases);
  79.             }
  80.             return (T)obj;
  81.         }
  82.         public static T GetFieldOrPropertyValue<T>(string fieldName, object obj, bool includeAllBases = false, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
  83.         {
  84.             FieldInfo field = obj.GetType().GetField(fieldName, bindings);
  85.             if (field != null) return (T)field.GetValue(obj);
  86.  
  87.             PropertyInfo property = obj.GetType().GetProperty(fieldName, bindings);
  88.             if (property != null) return (T)property.GetValue(obj, null);
  89.  
  90.             if (includeAllBases)
  91.             {
  92.                 foreach (Type type in GetBaseClassesAndInterfaces(obj.GetType()))
  93.                 {
  94.                     field = type.GetField(fieldName, bindings);
  95.                     if (field != null) return (T)field.GetValue(obj);
  96.  
  97.                     property = type.GetProperty(fieldName, bindings);
  98.                     if (property != null) return (T)property.GetValue(obj, null);
  99.                 }
  100.             }
  101.  
  102.             return default(T);
  103.         }
  104.         public static void SetFieldOrPropertyValue<T>(string fieldName, object obj, object value, bool includeAllBases = false, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
  105.         {
  106.             FieldInfo field = obj.GetType().GetField(fieldName, bindings);
  107.             if (field != null)
  108.             {
  109.                 field.SetValue(obj, value);
  110.                 return;
  111.             }
  112.  
  113.             PropertyInfo property = obj.GetType().GetProperty(fieldName, bindings);
  114.             if (property != null)
  115.             {
  116.                 property.SetValue(obj, value, null);
  117.                 return;
  118.             }
  119.  
  120.             if (includeAllBases)
  121.             {
  122.                 foreach (Type type in GetBaseClassesAndInterfaces(obj.GetType()))
  123.                 {
  124.                     field = type.GetField(fieldName, bindings);
  125.                     if (field != null)
  126.                     {
  127.                         field.SetValue(obj, value);
  128.                         return;
  129.                     }
  130.  
  131.                     property = type.GetProperty(fieldName, bindings);
  132.                     if (property != null)
  133.                     {
  134.                         property.SetValue(obj, value, null);
  135.                         return;
  136.                     }
  137.                 }
  138.             }
  139.         }
  140.         public static IEnumerable<Type> GetBaseClassesAndInterfaces(this Type type, bool includeSelf = false)
  141.         {
  142.             List<Type> allTypes = new List<Type>();
  143.  
  144.             if (includeSelf) allTypes.Add(type);
  145.  
  146.             if (type.BaseType == typeof(object))
  147.             {
  148.                 allTypes.AddRange(type.GetInterfaces());
  149.             }
  150.             else
  151.             {
  152.                 allTypes.AddRange(
  153.                         Enumerable
  154.                         .Repeat(type.BaseType, 1)
  155.                         .Concat(type.GetInterfaces())
  156.                         .Concat(type.BaseType.GetBaseClassesAndInterfaces())
  157.                         .Distinct());
  158.                 //I found this on stackoverflow
  159.             }
  160.  
  161.             return allTypes;
  162.         }
  163.     }
  164.  
  165.  
  166.     /*
  167.     [CustomPropertyDrawer(typeof(ActiveField<float>))]
  168.     public class ActiveFieldEditor : PropertyDrawer
  169.     {
  170.         public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
  171.         {
  172.             return base.GetPropertyHeight(property, label) * 3;
  173.         }
  174.         public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
  175.         {
  176.             var freeRect = EditorGUI.PrefixLabel(position, new GUIContent($"He-he"));
  177.             base.OnGUI(position, property, label);
  178.             */
  179.     /*
  180.     using (var scope = new EditorGUI.PropertyScope(position, label, property))
  181.     {
  182.         var freeRect = EditorGUI.PrefixLabel(position, new GUIContent($"He-he"));
  183.     }
  184.     */
  185.     /*
  186.     var minLimit = property.FindPropertyRelative("minLimit");
  187.     var maxLimit = property.FindPropertyRelative("maxLimit");
  188.     var minValue = property.FindPropertyRelative("minValue");
  189.     var maxValue = property.FindPropertyRelative("maxValue");
  190.     using (var scope = new EditorGUI.PropertyScope(position, label, property))
  191.     {
  192.         var freeRect = EditorGUI.PrefixLabel(position, new GUIContent($"{minLimit.floatValue}|{maxLimit.floatValue}"));
  193.         var lineSize = freeRect.height / 3;
  194.  
  195.         EditorGUI.BeginChangeCheck();
  196.         var minValueFloat = minValue.floatValue;
  197.         var maxValueFloat = maxValue.floatValue;
  198.         var sliderRect = new Rect(freeRect.x, freeRect.y, freeRect.width, lineSize);
  199.         EditorGUI.MinMaxSlider(sliderRect, ref minValueFloat, ref maxValueFloat, minLimit.floatValue, maxLimit.floatValue);
  200.  
  201.         var minLimitRect = new Rect(freeRect.x, freeRect.y + 1 * lineSize, freeRect.width, lineSize);
  202.         var maxLimitRect = new Rect(freeRect.x, freeRect.y + 2 * lineSize, freeRect.width, lineSize);
  203.         var minLimitFloat = EditorGUI.FloatField(new Rect(minLimitRect), "Min limit", minLimit.floatValue);
  204.         var maxLimitFloat = EditorGUI.FloatField(new Rect(maxLimitRect), "Max limit", maxLimit.floatValue);
  205.  
  206.         if (EditorGUI.EndChangeCheck())
  207.         {
  208.             minLimit.floatValue = minLimitFloat;
  209.             maxLimit.floatValue = maxLimitFloat;
  210.             minValue.floatValue = minValueFloat;
  211.             maxValue.floatValue = maxValueFloat;
  212.         }
  213.     }
  214.     */
  215.     /*}
  216.         }*/
  217.     //    [CustomEditor(typeof(ActiveField<>))]
  218.     //    class GenericActiveFieldEditor : Editor
  219.     //    {
  220.     //        public override void OnInspectorGUI()
  221.     //        {
  222.     //            EditorGUILayout.LabelField("I'm shown OK generic");
  223.     //        }
  224.     //    }
  225.     //    [CustomEditor(typeof(ActiveField<float>))]
  226.     //    class FloatActiveFieldEditor: Editor
  227.     //    {
  228.     //        public override void OnInspectorGUI()
  229.     //        {
  230.     //            EditorGUILayout.LabelField("I'm shown OK float");
  231.     //        }
  232.     //    }
  233. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement