// Entry Point public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { if (showDebug) { Rect sliderRect = new Rect(0, position.y, position.width, normalHeight); labelWidthPercent = EditorGUI.Slider(sliderRect, labelWidthPercent, 0, 1); sliderRect.y += debugTool; position.yMin += debugTool; } float yMax = position.yMax; currHeight = 0; EditorGUI.indentLevel = 0; isCalcHeight = false; SetupGUIStyle(); // Inspector Label Width labelWidth = position.width * labelWidthPercent; EditorGUIUtility.labelWidth = labelWidth; currProperty = property.propertyPath; SerializedProperty origProp = null; // Special case of array element (4.3) if (SerializedPropertyUtility.IsArrayElement(property)) { isArrayElement = true; arrayElementIndex = SerializedPropertyUtility.IndexOfArrayElement(property); origProp = SerializedPropertyUtility.GetArrayParentProperty(property); } else { origProp = property.Copy(); } AutoPropertyField(position, property, origProp, label, 0, out yMax); // delay action if (action != null) { action.Action(); action = null; } GUI.skin = null; }
// For each array element (include size) bool AutoArrayField(Rect position, SerializedProperty prop, SerializedProperty origProp, GUIContent label, int level, out float yMax) { bool bNextVisible = true; yMax = position.yMax; Rect newPos = new Rect(position); newPos.y += marginWidth.y; newPos.height = normalHeight; Vector2 xRangeFrame = new Vector2(GetXRange(prop) + frameWidth, position.xMax - GetXRange(prop) - frameWidth); // Frame Box if (!isCalcHeight) { Rect boxRect = new Rect(position); boxRect.x = xRangeFrame[0]; boxRect.xMax = xRangeFrame[1]; //boxRect.yMax = yMax; string storeCurrProp = currProperty; boxRect.height = this.GetPropertyHeight(prop, origProp, label); currProperty = storeCurrProp; if (prop.depth % 2 == 0) { if (EditorGUIUtility.isProSkin) { GUI.Box(boxRect, "", "box"); } else { GUI.Box(boxRect, "", "box"); } } else { GUI.Box(boxRect, "", "box"); } } // Array Index int i = -1; bool bArrayEleSpecialCase = false; if (isArrayElement) { i = arrayElementIndex; isArrayElement = false; bArrayEleSpecialCase = true; } do { Vector2 xRangeContent = new Vector2(GetXRange(prop) + marginWidth.x, position.xMax - GetXRange(prop) - marginWidth.x); bool bGeneric = false; // Get displayName by Reflection if (!isCalcHeight) { label.text = prop.displayName; } float elementWidth = labelWidth; if (i >= 0) { elementWidth = arrayElementWidth; // array element } // Is Array Element if (!isCalcHeight && (origProp.isArray && (origProp.isExpanded || bArrayEleSpecialCase))) { if (i >= 0) { // Label label.text = " "; Rect toolPos = new Rect(elementWidth + xRangeContent[0] - foldoutWidth, newPos.y, smallHeight, smallHeight); // Array element move up GUI.enabled = i > 0; if (GUI.Button(toolPos, "^")) { if (origProp.MoveArrayElement(i, i - 1)) { bool temp = origProp.GetArrayElementAtIndex(i).isExpanded; origProp.GetArrayElementAtIndex(i).isExpanded = origProp.GetArrayElementAtIndex(i - 1).isExpanded; origProp.GetArrayElementAtIndex(i - 1).isExpanded = temp; } } toolPos.x += smallHeight; // Array element move down GUI.enabled = i < origProp.arraySize - 1; if (GUI.Button(toolPos, "v")) { if (origProp.MoveArrayElement(i, i + 1)) { bool temp = origProp.GetArrayElementAtIndex(i).isExpanded; origProp.GetArrayElementAtIndex(i).isExpanded = origProp.GetArrayElementAtIndex(i + 1).isExpanded; origProp.GetArrayElementAtIndex(i + 1).isExpanded = temp; } } toolPos.x += smallHeight; // Array element remove GUI.enabled = origProp.arraySize > 0; if (GUI.Button(toolPos, "-")) { action = new InsertDeleteElement(origProp, false, i); } toolPos.x += smallHeight; // Array element insert GUI.enabled = true; if (GUI.Button(toolPos, "+")) { action = new InsertDeleteElement(origProp, true, i); } toolPos.x += smallHeight; // Array Element Label string elementIDStr = string.Format("{0}", i); if (!prop.hasVisibleChildren && !prop.isExpanded) { var nextDisplayName = "[" + elementIDStr + "]"; GUI.Label(new Rect(toolPos.x, toolPos.y, nextDisplayName.Length * 10, toolPos.height), nextDisplayName); } else { var nextProp = prop.Copy(); if (nextProp.NextVisible(true) && nextProp.propertyType == SerializedPropertyType.String) { var nextDisplayName = "[" + elementIDStr + "] = \"" + nextProp.stringValue + "\""; GUI.Label(new Rect(toolPos.x, toolPos.y, nextDisplayName.Length * 10, toolPos.height), nextDisplayName); } } } } // Is Array or Custom class if (prop.propertyType == SerializedPropertyType.Generic && (prop.isArray || prop.hasChildren)) { // Fold out if (!isCalcHeight) { prop.isExpanded = EditorGUI.Foldout(new Rect(xRangeContent[0] - foldoutWidth, newPos.y, elementWidth, normalHeight), prop.isExpanded, label.text); } newPos.y += normalHeight; if (prop.isExpanded) { // Enter children SerializedProperty parentProp = prop.Copy(); bNextVisible = prop.NextVisible(true); if (!bNextVisible) { return(bNextVisible); } // Into Generic Property bNextVisible = AutoPropertyField(newPos, prop, parentProp, label, level + 1, out yMax); newPos.y = yMax; bGeneric = true; } } else { // CustomPropertyField(newPos, prop, label, out yMax); newPos.y = yMax; } // special case if (bArrayEleSpecialCase) { bNextVisible = false; bArrayEleSpecialCase = false; } // Next Visible if (!bGeneric && bNextVisible) { bNextVisible = prop.NextVisible(false); } i++; } while (bNextVisible && prop.depth > origProp.depth); yMax = newPos.y + marginWidth.y; return(bNextVisible); }