Ejemplo n.º 1
0
 /// <summary>
 /// Draws the specified object.
 /// </summary>
 /// <param name="guiContent">The GUIContent to draw with the associated object.</param>
 /// <param name="type">The type of object to draw.</param>
 /// <param name="value">The value of the object.</param>
 /// <param name="name">The name of the object being drawn.</param>
 /// <param name="hashPrefix">The prefix of the hash from the parent class. This value will prevent collisions with similarly named objects.</param>
 /// <param name="valuePositionMap">A map between the value hash and the position within the positions array.</param>
 /// <param name="serialization">The serialized data.</param>
 /// <param name="fieldProperty">A reference to the field or property that is being drawn.</param>
 /// <param name="drawFields">Should the fields be drawn? If false the properties will be drawn.</param>
 /// <returns>The drawn object.</returns>
 private static object DrawSingleObject(GUIContent guiContent, Type type, object value, string name, int hashPrefix, Dictionary <int, int> valuePositionMap, Serialization serialization, object fieldProperty, bool drawFields)
 {
     if (type == typeof(int))
     {
         return(EditorGUILayout.IntField(guiContent, (int)value));
     }
     if (type == typeof(float))
     {
         // The range attribute may be used instead.
         if (drawFields)
         {
             var field          = (System.Reflection.FieldInfo)fieldProperty;
             var rangeAttribute = field.GetCustomAttributes(typeof(RangeAttribute), false) as RangeAttribute[];
             if (rangeAttribute != null && rangeAttribute.Length > 0)
             {
                 return(EditorGUILayout.Slider(guiContent, (float)value, rangeAttribute[0].min, rangeAttribute[0].max));
             }
         }
         return(EditorGUILayout.FloatField(guiContent, (float)value));
     }
     if (type == typeof(double))
     {
         return(EditorGUILayout.FloatField(guiContent, Convert.ToSingle((double)value)));
     }
     if (type == typeof(long))
     {
         return((long)EditorGUILayout.IntField(guiContent, Convert.ToInt32((long)value)));
     }
     if (type == typeof(bool))
     {
         return(EditorGUILayout.Toggle(guiContent, (bool)value));
     }
     if (type == typeof(string))
     {
         return(EditorGUILayout.TextField(guiContent, (string)value));
     }
     if (type == typeof(byte))
     {
         return(Convert.ToByte(EditorGUILayout.IntField(guiContent, Convert.ToInt32(value))));
     }
     if (type == typeof(Vector2))
     {
         return(EditorGUILayout.Vector2Field(guiContent, (Vector2)value));
     }
     if (type == typeof(Vector3))
     {
         return(EditorGUILayout.Vector3Field(guiContent, (Vector3)value));
     }
     if (type == typeof(Vector4))
     {
         return(EditorGUILayout.Vector4Field(guiContent, (Vector4)value));
     }
     if (type == typeof(Quaternion))
     {
         var quaternion  = (Quaternion)value;
         var vectorValue = Vector4.zero;
         vectorValue.Set(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
         vectorValue = EditorGUILayout.Vector4Field(name, vectorValue);
         quaternion.Set(vectorValue.x, vectorValue.y, vectorValue.z, vectorValue.w);
         return(quaternion);
     }
     if (type == typeof(Color))
     {
         return(EditorGUILayout.ColorField(guiContent, (Color)value));
     }
     if (type == typeof(Rect))
     {
         return(EditorGUILayout.RectField(guiContent, (Rect)value));
     }
     if (type == typeof(Matrix4x4))
     {
         var matrix = (Matrix4x4)value;
         if (InspectorUtility.Foldout(value, guiContent))
         {
             EditorGUI.indentLevel++;
             for (int i = 0; i < 4; ++i)
             {
                 for (int j = 0; j < 4; ++j)
                 {
                     matrix[i, j] = EditorGUILayout.FloatField("E" + i.ToString() + j.ToString(), matrix[i, j]);
                 }
             }
             EditorGUI.indentLevel--;
         }
         return(matrix);
     }
     if (type == typeof(AnimationCurve))
     {
         if (value == null)
         {
             value       = AnimationCurve.EaseInOut(0, 0, 1, 1);
             GUI.changed = true;
         }
         return(EditorGUILayout.CurveField(guiContent, (AnimationCurve)value));
     }
     if (type == typeof(LayerMask))
     {
         return(DrawLayerMask(guiContent, (LayerMask)value));
     }
     if (type.IsEnum)
     {
         if (type.IsDefined(typeof(FlagsAttribute), true))
         {
             return(EditorGUILayout.MaskField(guiContent, (int)value, Enum.GetNames(type)));
         }
         return(EditorGUILayout.EnumPopup(guiContent, (Enum)Enum.ToObject(type, value)));
     }
     if (typeof(UnityEngine.Object).IsAssignableFrom(type))
     {
         return(EditorGUILayout.ObjectField(guiContent, (UnityEngine.Object)value, type, true));
     }
     if (type.IsClass || (type.IsValueType && !type.IsPrimitive)) // Classes and structs.
     {
         if (typeof(Delegate).IsAssignableFrom(type))             // Delegates are not supported.
         {
             return(null);
         }
         if (s_DrawnObjects == null)
         {
             s_DrawnObjects = new HashSet <int>();
         }
         // Do not endlessly loop on objects that have already been drawn.
         var hash = name.GetHashCode();
         if (s_DrawnObjects.Contains(hash))
         {
             return(null);
         }
         else
         {
             try { // Unity may throw an exception so catch it to clean up.
                 s_DrawnObjects.Add(hash);
                 GUILayout.BeginVertical();
                 if (value == null)
                 {
                     value       = Activator.CreateInstance(type);
                     GUI.changed = true;
                 }
                 if (InspectorUtility.Foldout(value, guiContent))
                 {
                     EditorGUI.indentLevel++;
                     var inspectorDrawer = InspectorDrawerUtility.InspectorDrawerForType(type);
                     if (inspectorDrawer != null)
                     {
                         inspectorDrawer.OnInspectorGUI(value, null);
                     }
                     else if (drawFields)
                     {
                         value = DrawFields(value, true, hashPrefix + Serialization.StringHash(type.FullName) + Serialization.StringHash(name));
                     }
                     else
                     {
                         value = DrawProperties(type, value, hashPrefix + Serialization.StringHash(type.FullName) + Serialization.StringHash(name), valuePositionMap, serialization, MemberVisibility.Public, null, null);
                     }
                     EditorGUI.indentLevel--;
                 }
                 GUILayout.EndVertical();
                 s_DrawnObjects.Remove(hash);
                 return(value);
             } catch (Exception /*e*/) {
                 // Clean up any exceptions.
                 EditorGUI.indentLevel--;
                 GUILayout.EndVertical();
                 s_DrawnObjects.Remove(hash);
                 return(null);
             }
         }
     }
     Debug.LogWarning("Warning: unsupported value type: " + type);
     return(null);
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Draws the specified array object.
        /// </summary>
        /// <param name="guiContent">The GUIContent to draw with the associated object.</param>
        /// <param name="type">The type of object to draw.</param>
        /// <param name="parent">The parent of the value.</param>
        /// <param name="value">The value of the object.</param>
        /// <param name="name">The name of the object being drawn.</param>
        /// <param name="hashPrefix">The prefix of the hash from the parent class. This value will prevent collisions with similarly named objects.</param>
        /// <param name="valuePositionMap">A map between the value hash and the position within the positions array.</param>
        /// <param name="serialization">The serialized data.</param>
        /// <param name="fieldProperty">A reference to the field or property that is being drawn.</param>
        /// <param name="drawFields">Should the fields be drawn? If false the properties will be drawn.</param>
        /// <returns>The drawn object.</returns>
        private static object DrawArrayObject(GUIContent guiContent, Type type, object parent, object value, string name, int hashPrefix, Dictionary <int, int> valuePositionMap, Serialization serialization, object fieldProperty, bool drawFields)
        {
            // Arrays and lists operate differently when retrieving the element type.
            Type elementType;

            if (type.IsArray)
            {
                elementType = type.GetElementType();
            }
            else
            {
                var baseFieldType = type;
                while (!baseFieldType.IsGenericType)
                {
                    baseFieldType = baseFieldType.BaseType;
                }
                elementType = baseFieldType.GetGenericArguments()[0];
            }

            // Create the list value if it is null. The list cannot be null.
            IList list;

            if (value == null)
            {
                if (type.IsGenericType || type.IsArray)
                {
                    list = Activator.CreateInstance(typeof(List <>).MakeGenericType(elementType), true) as IList;
                }
                else
                {
                    list = Activator.CreateInstance(type, true) as IList;
                }
                if (type.IsArray)
                {
                    // Copy to an array so SetValue will accept the new value.
                    var array = Array.CreateInstance(elementType, list.Count);
                    list.CopyTo(array, 0);
                    list = array;
                }
            }
            else
            {
                list = (IList)value;
            }

            EditorGUILayout.BeginVertical();
            if (InspectorUtility.Foldout(list, guiContent))
            {
                EditorGUI.indentLevel++;
                var hash = hashPrefix + (parent != null ? parent.GetHashCode() : 0) + Serialization.StringHash(type.FullName) + Serialization.StringHash(name);
                // s_EditingArray is static so s_FocusHash is necessary so the array that is being modified can be identified.
                if (s_EditingArray && s_FocusHash == hash && (s_KeybordControl != GUIUtility.keyboardControl || Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter))
                {
                    s_EditingArray = false;
                    var newArray    = Array.CreateInstance(elementType, s_ArraySize);
                    var origElement = -1;
                    // Copy all of the old values to the new array.
                    for (int i = 0; i < s_ArraySize; ++i)
                    {
                        if (i < list.Count)
                        {
                            origElement = i;
                        }
                        if (origElement == -1)
                        {
                            break;
                        }

                        var listValue = list[origElement];
                        if (i >= list.Count && !typeof(UnityEngine.Object).IsAssignableFrom(elementType) && !typeof(string).IsAssignableFrom(elementType))
                        {
                            // Do not copy by reference.
                            listValue = Activator.CreateInstance(list[origElement].GetType(), true);
                        }

                        newArray.SetValue(listValue, i);
                    }
                    if (type.IsArray)
                    {
                        list = (IList)newArray;
                    }
                    else
                    {
                        if (type.IsGenericType)
                        {
                            list = Activator.CreateInstance(typeof(List <>).MakeGenericType(elementType), true) as IList;
                        }
                        else
                        {
                            list = Activator.CreateInstance(type, true) as IList;
                        }
                        for (int i = 0; i < newArray.Length; ++i)
                        {
                            list.Add(newArray.GetValue(i));
                        }
                    }
                    // Mark the GUI as changed so the object will be serialized.
                    GUI.changed = true;
                }
                var size = EditorGUILayout.IntField("Size", list.Count);
                if (size != list.Count)
                {
                    if (!s_EditingArray)
                    {
                        s_EditingArray   = true;
                        s_KeybordControl = GUIUtility.keyboardControl;
                        s_FocusHash      = hash;
                    }
                    s_ArraySize = size;
                }

                hash = hashPrefix + Serialization.StringHash(type.FullName) + Serialization.StringHash(name);
                for (int i = 0; i < list.Count; ++i)
                {
                    GUILayout.BeginHorizontal();
                    if (list[i] == null && !typeof(UnityEngine.Object).IsAssignableFrom(elementType) && elementType != typeof(string))
                    {
                        list[i] = Activator.CreateInstance(elementType);
                    }
                    guiContent.text = "Element " + i;
                    list[i]         = DrawObject(guiContent, elementType, parent, list[i], name, hash / (i + 2), valuePositionMap, serialization, fieldProperty, drawFields);
                    GUILayout.Space(6);
                    GUILayout.EndHorizontal();
                }
                EditorGUI.indentLevel--;
            }
            EditorGUILayout.EndVertical();
            return(list);
        }