//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;
        }