// Only EditorGUI.DefaultPropertyField is replaced with EditorGUIHelper.DefaultPropertyFieldDelayed private static bool OnGUIDelayed(this PropertyHandler handler, Rect position, SerializedProperty property, GUIContent label, bool includeChildren) { Rect visibleArea = new Rect(0f, 0f, float.MaxValue, float.MaxValue); handler.TestInvalidateCache(); float oldLabelWidth, oldFieldWidth; float propHeight = position.height; position.height = 0; if (handler.m_DecoratorDrawers != null && !handler.isCurrentlyNested) { foreach (DecoratorDrawer decorator in handler.m_DecoratorDrawers) { position.height = decorator.GetHeight(); oldLabelWidth = EditorGUIUtility.labelWidth; oldFieldWidth = EditorGUIUtility.fieldWidth; decorator.OnGUI(position); EditorGUIUtility.labelWidth = oldLabelWidth; EditorGUIUtility.fieldWidth = oldFieldWidth; position.y += position.height; propHeight -= position.height; } } position.height = propHeight; if (handler.propertyDrawer != null) { // Remember widths oldLabelWidth = EditorGUIUtility.labelWidth; oldFieldWidth = EditorGUIUtility.fieldWidth; // Draw with custom drawer handler.propertyDrawer.OnGUISafe(position, property.Copy(), label ?? EditorGUIUtility.TempContent(property.localizedDisplayName)); // Restore widths EditorGUIUtility.labelWidth = oldLabelWidth; EditorGUIUtility.fieldWidth = oldFieldWidth; return(false); } if (PropertyHandler.IsNonStringArray(property)) { string key = ReorderableListWrapper.GetPropertyIdentifier(property); if (!PropertyHandler.s_reorderableLists.TryGetValue(key, out ReorderableListWrapper reorderableList)) { throw new IndexOutOfRangeException( $"collection with name \"{property.name}\" doesn't have ReorderableList assigned to it."); } reorderableList.Property = property; reorderableList.Draw(position, visibleArea); return(false); } if (!includeChildren) { return(EditorGUIHelper.DefaultPropertyFieldDelayed(position, property, label)); } // Remember state Vector2 oldIconSize = EditorGUIUtility.GetIconSize(); bool wasEnabled = GUI.enabled; int origIndent = EditorGUI.indentLevel; int relIndent = origIndent - property.depth; SerializedProperty prop = property.Copy(); position.height = EditorGUI.GetSinglePropertyHeight(prop, label); // First property with custom label EditorGUI.indentLevel = prop.depth + relIndent; bool childrenAreExpanded = EditorGUIHelper.DefaultPropertyFieldDelayed(position, prop, label) && EditorGUI.HasVisibleChildFields(prop); position.y += position.height + EditorGUI.kControlVerticalSpacing; // Loop through all child properties if (childrenAreExpanded) { SerializedProperty endProperty = prop.GetEndProperty(); while (prop.NextVisible(childrenAreExpanded) && !SerializedProperty.EqualContents(prop, endProperty)) { var childHandler = ScriptAttributeUtility.GetHandler(prop); EditorGUI.indentLevel = prop.depth + relIndent; position.height = childHandler.GetHeight(prop, null, false); if (position.Overlaps(visibleArea)) { EditorGUI.BeginChangeCheck(); childrenAreExpanded = childHandler.OnGUIDelayed(position, prop, null, false) && EditorGUI.HasVisibleChildFields(prop); // Changing child properties (like array size) may invalidate the iterator, // so stop now, or we may get errors. if (EditorGUI.EndChangeCheck()) { break; } } position.y += position.height + EditorGUI.kControlVerticalSpacing; } } // Restore state GUI.enabled = wasEnabled; EditorGUIUtility.SetIconSize(oldIconSize); EditorGUI.indentLevel = origIndent; return(false); }