public static bool IsComplex(SerializedProperty sProp)
        {
            var type = sProp.propertyType;

            switch (type)
            {
            case SerializedPropertyType.Generic:
                return(true);

            case SerializedPropertyType.ManagedReference:
            {
                var objValue     = PropertyValueHelper.GetTargetObjectOfProperty(sProp);
                var simpleDrawer = GetSimpleDrawerForManagedReference(objValue?.GetType(), objValue, null);
                return(simpleDrawer == null);
            }
            }

            return(false);
        }
        protected static Type GetCustomElementTypeForProperty(SerializedProperty property)
        {
            PropertyValueHelper.GetTargetObjectOfProperty(property, out FieldInfo fieldInfo);
            var fieldType = PropertyValueHelper.GetFieldType(fieldInfo);

            if (fieldType != null)
            {
                var elementTypes = TypeCache.GetTypesDerivedFrom <BasePropertyFieldElement>().ToArray();

                foreach (var t in elementTypes)
                {
                    var attribute = t.GetCustomAttribute <CustomPropertyElementAttribute>();

                    if (attribute != null && attribute.PropertyType.IsAssignableFrom(fieldType))
                    {
                        return(t);
                    }
                }
            }

            return(null);
        }
        // woa
        private static VisualElement CreateFieldByPropertyType(SerializedProperty property, object curValue, Action <object, object> onValueChanged)
        {
            var simpleField = CreateFieldByPropertyTypeSimple(property.propertyType, curValue, onValueChanged);

            if (simpleField != null)
            {
                return(simpleField);
            }
            var type = property.propertyType;

            switch (type)
            {
            case SerializedPropertyType.Color:
                return(BindChange(new ColorField()
                {
                    value = (Color)curValue
                }, onValueChanged));

            case SerializedPropertyType.ObjectReference:
                PropertyValueHelper.GetTargetObjectOfProperty(property, out Type fieldType);
                return(BindChange(new ObjectField()
                {
                    value = (UnityEngine.Object)curValue, objectType = fieldType, allowSceneObjects = false
                }, onValueChanged));

            case SerializedPropertyType.Vector2:
                return(BindChange(new Vector2Field()
                {
                    value = (Vector2)curValue
                }, onValueChanged));

            case SerializedPropertyType.Vector3:
                return(BindChange(new Vector3Field()
                {
                    value = (Vector3)curValue
                }, onValueChanged));

            case SerializedPropertyType.Vector4:
                return(BindChange(new Vector4Field()
                {
                    value = (Vector4)curValue
                }, onValueChanged));

            case SerializedPropertyType.Rect:
                return(BindChange(new RectField()
                {
                    value = (Rect)curValue
                }, onValueChanged));

            case SerializedPropertyType.ArraySize:
                return(BindChange(new IntegerField()
                {
                    value = (int)curValue, isDelayed = true
                }, onValueChanged));

            case SerializedPropertyType.Enum:
                return(BindChange(new EnumField(defaultValue: (Enum)PropertyValueHelper.GetTargetObjectOfProperty(property)), onValueChanged));

            case SerializedPropertyType.AnimationCurve:
                return(BindChange(new CurveField()
                {
                    value = (AnimationCurve)curValue
                }, onValueChanged));

            case SerializedPropertyType.Bounds:
                return(BindChange(new BoundsField()
                {
                    value = (Bounds)curValue
                }, onValueChanged));

            case SerializedPropertyType.Vector2Int:
                return(BindChange(new Vector2IntField()
                {
                    value = (Vector2Int)curValue
                }, onValueChanged));

            case SerializedPropertyType.Vector3Int:
                return(BindChange(new Vector3IntField()
                {
                    value = (Vector3Int)curValue
                }, onValueChanged));

            case SerializedPropertyType.RectInt:
                return(BindChange(new RectIntField()
                {
                    value = (RectInt)curValue
                }, onValueChanged));

            case SerializedPropertyType.BoundsInt:
                return(BindChange(new BoundsIntField()
                {
                    value = (BoundsInt)curValue
                }, onValueChanged));

            case SerializedPropertyType.ManagedReference:
                var objValue     = PropertyValueHelper.GetTargetObjectOfProperty(property);
                var simpleDrawer = GetSimpleDrawerForManagedReference(objValue?.GetType(), objValue, onValueChanged);
                if (simpleDrawer != null)
                {
                    return(simpleDrawer);
                }
                else
                {
                    return(NotSupportedLabel);
                }

            default:
                return(NotSupportedLabel);
            }
        }
        // nice
        public static void SetValue(UnityEngine.Object target, string serializedPropertyPath, object value)
        {
            SerializedObject   sObject;
            SerializedProperty property;

            CreateSerializedObjectAndProperty(target, serializedPropertyPath, out sObject, out property);
            if (sObject == null || property == null)
            {
                return;
            }

            switch (property.propertyType)
            {
            case SerializedPropertyType.Integer:
                property.intValue = (int)value;
                break;

            case SerializedPropertyType.Boolean:
                property.boolValue = (bool)value;
                break;

            case SerializedPropertyType.Float:
                property.floatValue = (float)value;
                break;

            case SerializedPropertyType.String:
                property.stringValue = (string)value;
                break;

            case SerializedPropertyType.Color:
                property.colorValue = (Color)value;
                break;

            case SerializedPropertyType.ObjectReference:
                property.objectReferenceValue = (UnityEngine.Object)value;
                break;

            case SerializedPropertyType.LayerMask:
                property.intValue = (LayerMask)value;
                break;

            case SerializedPropertyType.Enum:
                property.enumValueIndex = (int)value;
                break;

            case SerializedPropertyType.Vector2:
                property.vector2Value = (Vector2)value;
                break;

            case SerializedPropertyType.Vector3:
                property.vector3Value = (Vector3)value;
                break;

            case SerializedPropertyType.Vector4:
                property.vector4Value = (Vector4)value;
                break;

            case SerializedPropertyType.Rect:
                property.rectValue = (Rect)value;
                break;

            case SerializedPropertyType.ArraySize:
                property.arraySize = (int)value;
                break;

            case SerializedPropertyType.AnimationCurve:
                property.animationCurveValue = (AnimationCurve)value;
                break;

            case SerializedPropertyType.Bounds:
                property.boundsValue = (Bounds)value;
                break;

            case SerializedPropertyType.Vector2Int:
                property.vector2IntValue = (Vector2Int)value;
                break;

            case SerializedPropertyType.Vector3Int:
                property.vector3IntValue = (Vector3Int)value;
                break;

            case SerializedPropertyType.RectInt:
                property.rectIntValue = (RectInt)value;
                break;

            case SerializedPropertyType.BoundsInt:
                property.boundsIntValue = (BoundsInt)value;
                break;

            case SerializedPropertyType.ManagedReference:
                property.managedReferenceValue = value;
                break;

            case SerializedPropertyType.Generic:
                PropertyValueHelper.SetTargetObjectOfProperty(property, value);
                break;
            }

            sObject.ApplyModifiedProperties();
            property.Dispose();
            sObject.Dispose();
        }
        // having fun here
        public static object GetValue(UnityEngine.Object target, string serializedPropertyPath)
        {
            SerializedObject   sObject;
            SerializedProperty property;

            CreateSerializedObjectAndProperty(target, serializedPropertyPath, out sObject, out property);
            if (sObject == null || property == null)
            {
                return(null);
            }

            object result;

            switch (property.propertyType)
            {
            case SerializedPropertyType.Integer:
                result = property.intValue;
                break;

            case SerializedPropertyType.Boolean:
                result = property.boolValue;
                break;

            case SerializedPropertyType.Float:
                result = property.floatValue;
                break;

            case SerializedPropertyType.String:
                result = property.stringValue;
                break;

            case SerializedPropertyType.Color:
                result = property.colorValue;
                break;

            case SerializedPropertyType.ObjectReference:
                result = property.objectReferenceValue;
                break;

            case SerializedPropertyType.LayerMask:
                result = (LayerMask)property.intValue;
                break;

            case SerializedPropertyType.Enum:
                result = property.enumValueIndex;
                break;

            case SerializedPropertyType.Vector2:
                result = property.vector2Value;
                break;

            case SerializedPropertyType.Vector3:
                result = property.vector3Value;
                break;

            case SerializedPropertyType.Vector4:
                result = property.vector4Value;
                break;

            case SerializedPropertyType.Rect:
                result = property.rectValue;
                break;

            case SerializedPropertyType.ArraySize:
                result = property.arraySize;
                break;

            case SerializedPropertyType.AnimationCurve:
                result = property.animationCurveValue;
                break;

            case SerializedPropertyType.Bounds:
                result = property.boundsValue;
                break;

            case SerializedPropertyType.Vector2Int:
                result = property.vector2IntValue;
                break;

            case SerializedPropertyType.Vector3Int:
                result = property.vector3IntValue;
                break;

            case SerializedPropertyType.RectInt:
                result = property.rectIntValue;
                break;

            case SerializedPropertyType.BoundsInt:
                result = property.boundsIntValue;
                break;

            case SerializedPropertyType.ManagedReference:
                result = PropertyValueHelper.GetTargetObjectOfProperty(property);
                break;

            case SerializedPropertyType.Generic:
                result = PropertyValueHelper.GetTargetObjectOfProperty(property);
                break;

            default:
                result = null;
                break;
            }

            property.Dispose();
            sObject.Dispose();
            return(result);
        }