///Returns a function that can convert from source type to target type with given func as the current value
        public static ValueHandler <T> GetConverterFuncFromTo <T>(Type sourceType, Type targetType, ValueHandler <object> func)
        {
            //assignables or upcasting
            if (targetType.RTIsAssignableFrom(sourceType) || targetType.RTIsSubclassOf(sourceType))
            {
                return(() => { return (T)func(); });
            }

            //convertibles
            if (typeof(IConvertible).RTIsAssignableFrom(targetType) && typeof(IConvertible).RTIsAssignableFrom(sourceType))
            {
                return(() => { return (T)Convert.ChangeType(func(), targetType); });
            }

            //handles implicit/explicit and prety much everything else.
            //invoke done with reflection to support all platforms.
            UnaryExpression exp = null;

            if (ReflectionTools.CanConvert(sourceType, targetType, out exp))
            {
                return(() => { try { return (T)exp.Method.Invoke(null, new object[] { func() }); } catch { return default(T); } });
            }

            ///CUSTOM CONVENIENCE CONVERSIONS
            ///----------------------------------------------------------------------------------------------

            //from anything to string
            if (targetType == typeof(string))
            {
                return(() => { try { return (T)(object)(func().ToString()); } catch { return default(T); } });
            }

            //from anything to Type
            if (targetType == typeof(Type))
            {
                return(() => { try { return (T)(object)func().GetType(); } catch { return default(T); } });
            }

            //from convertible to Vector3
            if (targetType == typeof(Vector3) && typeof(IConvertible).RTIsAssignableFrom(sourceType))
            {
                return(() =>
                {
                    var f = (float)Convert.ChangeType(func(), typeof(float));
                    return (T)(object)new Vector3(f, f, f);
                });
            }

            ///----------------------------------------------------------------------------------------------

            //from component to Vector3 (position)
            if (targetType == typeof(Vector3) && typeof(Component).RTIsAssignableFrom(sourceType))
            {
                return(() => { try { return (T)(object)((func() as Component).transform.position); } catch { return default(T); } });
            }

            //from gameobject to Vector3 (position)
            if (targetType == typeof(Vector3) && sourceType == typeof(GameObject))
            {
                return(() => { try { return (T)(object)((func() as GameObject).transform.position); } catch { return default(T); } });
            }

            //from component to Quaternion (rotation)
            if (targetType == typeof(Quaternion) && typeof(Component).RTIsAssignableFrom(sourceType))
            {
                return(() => { try { return (T)(object)((func() as Component).transform.rotation); } catch { return default(T); } });
            }

            //from gameobject to Quaternion (rotation)
            if (targetType == typeof(Quaternion) && sourceType == typeof(GameObject))
            {
                return(() => { try { return (T)(object)((func() as GameObject).transform.rotation); } catch { return default(T); } });
            }

            ///----------------------------------------------------------------------------------------------

            //from component to component
            if (typeof(Component).RTIsAssignableFrom(targetType) && typeof(Component).RTIsAssignableFrom(sourceType))
            {
                return(() => { try { return (T)(object)((func() as Component).GetComponent(targetType)); } catch { return default(T); } });
            }

            //from gameobject to component
            if (typeof(Component).RTIsAssignableFrom(targetType) && sourceType == typeof(GameObject))
            {
                return(() => { try { return (T)(object)((func() as GameObject).GetComponent(targetType)); } catch { return default(T); } });
            }

            //from component to gameobject
            if (targetType == typeof(GameObject) && typeof(Component).RTIsAssignableFrom(sourceType))
            {
                return(() => { try { return (T)(object)((func() as Component).gameObject); } catch { return default(T); } });
            }

            ///----------------------------------------------------------------------------------------------

            //From IEnumerable to IEnumerable for Lists and Arrays
            if (typeof(IEnumerable).RTIsAssignableFrom(sourceType) && typeof(IEnumerable).RTIsAssignableFrom(targetType))
            {
                try
                {
                    var elementFrom = sourceType.RTIsArray()? sourceType.GetElementType() : sourceType.GetGenericArguments().Single();
                    var elementTo   = targetType.RTIsArray()? targetType.GetElementType() : targetType.GetGenericArguments().Single();
                    if (elementTo.RTIsAssignableFrom(elementFrom))
                    {
                        var listType = typeof(List <>).RTMakeGenericType(elementTo);
                        return(() =>
                        {
                            var list = (IList)System.Activator.CreateInstance(listType);
                            foreach (var o in (IEnumerable)func())
                            {
                                list.Add(o);
                            }
                            return (T)list;
                        });
                    }
                }
                catch { return(null); }
            }

            return(null);
        }