/// <summary>
    /// Draw an enum field in inspector
    /// </summary>
    /// <param name="inspectedParameter"></param>
    /// <param name="label"></param>
    /// <param name="valueType"></param>
    /// <param name="oldValue"></param>
    /// <returns></returns>
    internal static object DrawEnum(InspectedField inspectedParameter, string label, Type valueType, object oldValue, List <InspectedField> fieldList)
    {
        if (inspectedParameter == null) // it's a newly add parameter for inspecting
        {
            //Make a new InspectedField and add it to the list.
            InspectedField iField = new InspectedField(label, (Enum)Enum.GetValues(valueType).GetValue(0), true, valueType);
            fieldList.Add(iField);

            return(EditorGUILayout.EnumFlagsField((Enum)Enum.GetValues(valueType).GetValue(0)));
        }
        else
        {
            Enum value = (Enum)Enum.GetValues(valueType).GetValue(0);
            if (oldValue is Enum)
            {
                value = (Enum)oldValue;
                inspectedParameter.Value = EditorGUILayout.EnumPopup(value);

                //Set the value return from user input from inspector to the InspectedParameterList
                return(inspectedParameter.Value);
            }
            else
            {
                Debug.LogFormat("{0} is not {1} type", label, valueType);
                return(null);
            }
        }
    }
    /// <summary>
    /// Draw a component field in inspector
    /// </summary>
    /// <param name="inspectedParameter"></param>
    /// <param name="label"></param>
    /// <param name="valueType"></param>
    /// <param name="oldValue"></param>
    /// <param name="fieldList"></param>
    /// <returns></returns>
    internal static object DrawComponent(InspectedField inspectedParameter, string label, Type valueType, object oldValue, List <InspectedField> fieldList)
    {
        UnityEngine.Component component = new UnityEngine.Component();

        if (inspectedParameter == null) // it's a newly add parameter for inspecting
        {
            //Make a new InspectedField and add it to the list.
            InspectedField iField = new InspectedField(label, component, true, valueType);
            fieldList.Add(iField);

            return(EditorGUILayout.ObjectField(label, component, valueType, true));
        }
        else
        {
            if (oldValue is UnityEngine.Component)
            {
                component = (UnityEngine.Component)oldValue;
                inspectedParameter.Value = EditorGUILayout.ObjectField(label, component, valueType, true);

                //Set the value return from user input from inspector to the InspectedParameterList
                return(inspectedParameter.Value);
            }
            else
            {
                Debug.LogFormat("{0} is not {1} type", label, valueType);
                return(null);
            }
        }
    }
    /// <summary>
    /// Draw boolean field in inspector
    /// </summary>
    /// <param name="inspectedParameter"></param>
    /// <param name="label"></param>
    /// <param name="valueType"></param>
    /// <param name="oldValue"></param>
    /// <returns></returns>
    internal static object DrawBool(InspectedField inspectedParameter, string label, Type valueType, object oldValue, List <InspectedField> fieldList)
    {
        if (inspectedParameter == null) // it's a newly add parameter for inspecting
        {
            //Make a new InspectedField and add it to the list.
            InspectedField iField = new InspectedField(label, false, true, valueType);
            fieldList.Add(iField);

            return(EditorGUILayout.Toggle(label, false));
        }
        else // we are inspecting the parameter
        {
            bool value = false;
            if (oldValue is bool)
            {
                value = (bool)oldValue;
                inspectedParameter.Value = EditorGUILayout.Toggle(label, value);

                //Set the value return from user input from inspector to the InspectedParameterList
                return(inspectedParameter.Value);
            }
            else
            {
                Debug.LogFormat("{0} is not {1} type", label, valueType);
                return(null);
            }
        }
    }
    /// <summary>
    /// Draw rect field in inspector
    /// </summary>
    /// <param name="inspectedParameter"></param>
    /// <param name="label"></param>
    /// <param name="valueType"></param>
    /// <param name="oldValue"></param>
    /// <returns></returns>
    internal static object DrawRect(InspectedField inspectedParameter, string label, Type valueType, object oldValue, List <InspectedField> fieldList)
    {
        if (inspectedParameter == null) // it's a newly add parameter for inspecting
        {
            //Make a new InspectedField and add it to the list.
            InspectedField iField = new InspectedField(label, Rect.zero, true, valueType);
            fieldList.Add(iField);

            return(EditorGUILayout.RectField(label, Rect.zero));
        }
        else
        {
            Rect value = Rect.zero;
            if (oldValue is Rect)
            {
                value = (Rect)oldValue;
                inspectedParameter.Value = EditorGUILayout.RectField(label, value);

                //Set the value return from user input from inspector to the InspectedParameterList
                return(inspectedParameter.Value);
            }
            else
            {
                Debug.LogFormat("{0} is not {1} type", label, valueType);
                return(null);
            }
        }
    }
    /// <summary>
    /// Method for drawing a inspected field with type and label, stored in fieldList and return the value return by inspector UIs
    /// </summary>
    /// <param name="fieldList"></param>
    /// <param name="valueType"></param>
    /// <param name="label"></param>
    /// <param name="returnValue"></param>
    /// <returns></returns>
    public bool DrawField(List <InspectedField> fieldList, Type valueType, string label, out object returnValue)
    {
        bool   isDrawn  = true;
        object oldValue = new object();

        //Check if we have been inspecting the parameter already
        InspectedField inspectedParameter = null;

        foreach (var para in fieldList)
        {
            if (para.Label.Equals(label) && para.FieldType == valueType)
            {
                para.IsInspected   = true;
                inspectedParameter = para;
                oldValue           = para.Value;
                break;
            }
        }

        DrawInspectedField drawer;
        var hasTypeDrawer = DrawerMap.TryGetValue(valueType, out drawer);

        if (hasTypeDrawer)
        {
            returnValue = drawer.Invoke(inspectedParameter, label, valueType, oldValue, fieldList);
        }
        else if (typeof(UnityEngine.Object).IsAssignableFrom(valueType))
        {
            returnValue = DrawObject(inspectedParameter, label, valueType, oldValue, fieldList);
        }
        else if (typeof(UnityEngine.Component).IsAssignableFrom(valueType))
        {
            returnValue = DrawComponent(inspectedParameter, label, valueType, oldValue, fieldList);
        }
        else if (valueType.BaseType == typeof(Enum))
        {
            returnValue = DrawEnum(inspectedParameter, label, valueType, oldValue, fieldList);
        }
        else
        {
            isDrawn     = false;
            returnValue = null;
        }

        return(isDrawn);
    }