// Retrieves an iterator that allows you to iterator over the current nexting of a serialized property. public System.Collections.IEnumerator GetEnumerator() { if (isArray) { for (int i = 0; i < arraySize; i++) { yield return(GetArrayElementAtIndex(i)); } } else { var end = GetEndProperty(); while (NextVisible(true) && !SerializedProperty.EqualContents(this, end)) { yield return(this); } } }
public bool CanCacheInspectorGUI(SerializedProperty property) { if (m_DecoratorDrawers != null && !isCurrentlyNested && m_DecoratorDrawers.Any(decorator => !decorator.CanCacheInspectorGUI())) { return(false); } if (propertyDrawer != null) { // Retrieve drawer BEFORE increasing nesting. PropertyDrawer drawer = propertyDrawer; using (var nestingContext = IncrementNestingContext()) { return(drawer.CanCacheInspectorGUISafe(property.Copy())); } } property = property.Copy(); bool childrenAreExpanded = property.isExpanded && EditorGUI.HasVisibleChildFields(property); // Loop through all child properties if (childrenAreExpanded) { PropertyHandler handler = null; SerializedProperty endProperty = property.GetEndProperty(); while (property.NextVisible(childrenAreExpanded) && !SerializedProperty.EqualContents(property, endProperty)) { if (handler == null) { handler = ScriptAttributeUtility.GetHandler(property); } if (!handler.CanCacheInspectorGUI(property)) { return(false); } childrenAreExpanded = false; } } return(true); }
public float GetHeight(SerializedProperty property, GUIContent label, bool includeChildren) { float height = 0; if (m_DecoratorDrawers != null && !isCurrentlyNested) { foreach (DecoratorDrawer drawer in m_DecoratorDrawers) { height += drawer.GetHeight(); } } if (propertyDrawer != null) { height += propertyDrawer.GetPropertyHeightSafe(property.Copy(), label ?? EditorGUIUtility.TempContent(property.displayName)); } else if (!includeChildren) { height += EditorGUI.GetSinglePropertyHeight(property, label); } else { property = property.Copy(); // First property with custom label height += EditorGUI.GetSinglePropertyHeight(property, label); bool childrenAreExpanded = property.isExpanded && EditorGUI.HasVisibleChildFields(property); // Loop through all child properties var tc = EditorGUIUtility.TempContent(property.displayName); if (childrenAreExpanded) { SerializedProperty endProperty = property.GetEndProperty(); while (property.NextVisible(childrenAreExpanded) && !SerializedProperty.EqualContents(property, endProperty)) { height += ScriptAttributeUtility.GetHandler(property).GetHeight(property, tc, true); childrenAreExpanded = false; height += EditorGUI.kControlVerticalSpacing; } } } return(height); }
private static void DoChildren(Rect position, SerializedProperty property) { position.height = 16f; EditorGUI.indentLevel++; SerializedProperty serializedProperty = property.Copy(); SerializedProperty endProperty = serializedProperty.GetEndProperty(); serializedProperty.NextVisible(true); while (!SerializedProperty.EqualContents(serializedProperty, endProperty)) { EditorGUI.PropertyField(position, serializedProperty); position.y += 16f; if (!serializedProperty.NextVisible(false)) { break; } } EditorGUI.indentLevel--; EditorGUILayout.Space(); }
public float GetHeight(SerializedProperty property, GUIContent label, bool includeChildren) { float num1 = 0.0f; if (this.m_DecoratorDrawers != null && !this.isCurrentlyNested) { using (List <DecoratorDrawer> .Enumerator enumerator = this.m_DecoratorDrawers.GetEnumerator()) { while (enumerator.MoveNext()) { DecoratorDrawer current = enumerator.Current; num1 += current.GetHeight(); } } } float num2; if (this.propertyDrawer != null) { num2 = num1 + this.propertyDrawer.GetPropertyHeightSafe(property.Copy(), label ?? EditorGUIUtility.TempContent(property.displayName)); } else if (!includeChildren) { num2 = num1 + EditorGUI.GetSinglePropertyHeight(property, label); } else { property = property.Copy(); SerializedProperty endProperty = property.GetEndProperty(); num2 = num1 + EditorGUI.GetSinglePropertyHeight(property, label); bool enterChildren = property.isExpanded && EditorGUI.HasVisibleChildFields(property); while (property.NextVisible(enterChildren) && !SerializedProperty.EqualContents(property, endProperty)) { float num3 = num2 + ScriptAttributeUtility.GetHandler(property).GetHeight(property, EditorGUIUtility.TempContent(property.displayName), true); enterChildren = false; num2 = num3 + 2f; } } return(num2); }
private void UpdatePrecompiledReferenceListEntry() { var precompiledAssemblyNames = CompilationPipeline.GetPrecompiledAssemblyNames().ToList(); var currentReferencesProp = extraDataSerializedObject.FindProperty("precompiledReferences"); if (currentReferencesProp.arraySize > 0) { var prop = currentReferencesProp.GetArrayElementAtIndex(0); var end = currentReferencesProp.GetEndProperty(); do { var fileName = prop.FindPropertyRelative("fileName").stringValue; if (!string.IsNullOrEmpty(fileName)) { precompiledAssemblyNames.Remove(fileName); } }while (prop.Next(false) && !SerializedProperty.EqualContents(prop, end)); } m_PrecompileReferenceListEntry = precompiledAssemblyNames .OrderBy(x => x).ToList(); }
static void AddComponentGUI(Object prefab) { var serialized = new SerializedObject(prefab); var i = serialized.FindProperty("m_Modification"); var end = i.GetEndProperty(); while (true) { var expanded = EditorGUILayout.PropertyField(i); if (!i.NextVisible(expanded)) { break; } if (SerializedProperty.EqualContents(i, end)) { break; } } serialized.ApplyModifiedProperties(); }
public float GetHeight(SerializedProperty property, GUIContent label, bool includeChildren) { float num = 0f; if (this.m_DecoratorDrawers != null) { foreach (DecoratorDrawer current in this.m_DecoratorDrawers) { num += current.GetHeight(); } } if (this.propertyDrawer != null) { num += this.propertyDrawer.GetPropertyHeightSafe(property.Copy(), label ?? EditorGUIUtility.TempContent(property.displayName)); } else { if (!includeChildren) { num += EditorGUI.GetSinglePropertyHeight(property, label); } else { property = property.Copy(); SerializedProperty endProperty = property.GetEndProperty(); num += EditorGUI.GetSinglePropertyHeight(property, label); bool enterChildren = property.isExpanded && EditorGUI.HasVisibleChildFields(property); while (property.NextVisible(enterChildren) && !SerializedProperty.EqualContents(property, endProperty)) { num += ScriptAttributeUtility.GetHandler(property).GetHeight(property, EditorGUIUtility.TempContent(property.displayName), true); enterChildren = false; num += 2f; } } } return(num); }
private static void DoChildren(Rect position, SerializedProperty property) { position.height = EditorGUI.kSingleLineHeight; EditorGUI.indentLevel++; SerializedProperty iterator = property.Copy(); var end = iterator.GetEndProperty(); iterator.NextVisible(true); while (!SerializedProperty.EqualContents(iterator, end)) { EditorGUI.PropertyField(position, iterator); position.y += EditorGUI.kSingleLineHeight; if (!iterator.NextVisible(false)) { break; } } EditorGUI.indentLevel--; EditorGUILayout.Space(); }
public bool OnGUI(Rect position, SerializedProperty property, GUIContent label, bool includeChildren) { float num = position.height; position.height = 0f; if (this.m_DecoratorDrawers != null && !this.isCurrentlyNested) { foreach (DecoratorDrawer current in this.m_DecoratorDrawers) { position.height = current.GetHeight(); float labelWidth = EditorGUIUtility.labelWidth; float fieldWidth = EditorGUIUtility.fieldWidth; current.OnGUI(position); EditorGUIUtility.labelWidth = labelWidth; EditorGUIUtility.fieldWidth = fieldWidth; position.y += position.height; num -= position.height; } } position.height = num; if (this.propertyDrawer != null) { float labelWidth = EditorGUIUtility.labelWidth; float fieldWidth = EditorGUIUtility.fieldWidth; this.propertyDrawer.OnGUISafe(position, property.Copy(), label ?? EditorGUIUtility.TempContent(property.displayName)); EditorGUIUtility.labelWidth = labelWidth; EditorGUIUtility.fieldWidth = fieldWidth; return(false); } if (!includeChildren) { return(EditorGUI.DefaultPropertyField(position, property, label)); } Vector2 iconSize = EditorGUIUtility.GetIconSize(); bool enabled = GUI.enabled; int indentLevel = EditorGUI.indentLevel; int num2 = indentLevel - property.depth; SerializedProperty serializedProperty = property.Copy(); SerializedProperty endProperty = serializedProperty.GetEndProperty(); position.height = EditorGUI.GetSinglePropertyHeight(serializedProperty, label); EditorGUI.indentLevel = serializedProperty.depth + num2; bool enterChildren = EditorGUI.DefaultPropertyField(position, serializedProperty, label) && EditorGUI.HasVisibleChildFields(serializedProperty); position.y += position.height + 2f; while (serializedProperty.NextVisible(enterChildren) && !SerializedProperty.EqualContents(serializedProperty, endProperty)) { EditorGUI.indentLevel = serializedProperty.depth + num2; position.height = EditorGUI.GetPropertyHeight(serializedProperty, null, false); EditorGUI.BeginChangeCheck(); enterChildren = (ScriptAttributeUtility.GetHandler(serializedProperty).OnGUI(position, serializedProperty, null, false) && EditorGUI.HasVisibleChildFields(serializedProperty)); if (EditorGUI.EndChangeCheck()) { break; } position.y += position.height + 2f; } GUI.enabled = enabled; EditorGUIUtility.SetIconSize(iconSize); EditorGUI.indentLevel = indentLevel; return(false); }
internal bool OnGUI(Rect position, SerializedProperty property, GUIContent label, bool includeChildren, Rect visibleArea) { float oldLabelWidth, oldFieldWidth; float propHeight = position.height; position.height = 0; if (m_DecoratorDrawers != null && !isCurrentlyNested) { foreach (DecoratorDrawer decorator in 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 (propertyDrawer != null) { // Remember widths oldLabelWidth = EditorGUIUtility.labelWidth; oldFieldWidth = EditorGUIUtility.fieldWidth; // Draw with custom drawer propertyDrawer.OnGUISafe(position, property.Copy(), label ?? EditorGUIUtility.TempContent(property.localizedDisplayName)); // Restore widths EditorGUIUtility.labelWidth = oldLabelWidth; EditorGUIUtility.fieldWidth = oldFieldWidth; return(false); } else { if (!includeChildren) { return(EditorGUI.DefaultPropertyField(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 = EditorGUI.DefaultPropertyField(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 handler = ScriptAttributeUtility.GetHandler(prop); EditorGUI.indentLevel = prop.depth + relIndent; position.height = handler.GetHeight(prop, null, false); if (position.Overlaps(visibleArea)) { EditorGUI.BeginChangeCheck(); childrenAreExpanded = handler.OnGUI(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); } }
// returns true if children needs to be drawn separately public bool OnGUI(Rect position, SerializedProperty property, GUIContent label, bool includeChildren) { // We can consider making controlIDs robust to support culling optimizations. // Works well - downside is that you can't use PrefixLabel before a PropertyField, // but PropertyField has build-in label argument anyway. //if (m_Hash == 0) // m_Hash = property.serializedObject.targetObject.GetInstanceID () ^ property.propertyPath.GetHashCode (); //EditorGUIUtility.GetControlID (m_Hash, FocusType.Passive); float oldLabelWidth, oldFieldWidth; float propHeight = position.height; position.height = 0; if (m_DecoratorDrawers != null && !isCurrentlyNested) { foreach (DecoratorDrawer decorator in 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 (propertyDrawer != null) { // Remember widths oldLabelWidth = EditorGUIUtility.labelWidth; oldFieldWidth = EditorGUIUtility.fieldWidth; // Draw with custom drawer propertyDrawer.OnGUISafe(position, property.Copy(), label ?? EditorGUIUtility.TempContent(property.localizedDisplayName)); // Restore widths EditorGUIUtility.labelWidth = oldLabelWidth; EditorGUIUtility.fieldWidth = oldFieldWidth; return(false); } else { if (!includeChildren) { return(EditorGUI.DefaultPropertyField(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(); SerializedProperty endProperty = prop.GetEndProperty(); position.height = EditorGUI.GetSinglePropertyHeight(prop, label); // First property with custom label EditorGUI.indentLevel = prop.depth + relIndent; bool childrenAreExpanded = EditorGUI.DefaultPropertyField(position, prop, label) && EditorGUI.HasVisibleChildFields(prop); position.y += position.height + EditorGUI.kControlVerticalSpacing; // Loop through all child properties while (prop.NextVisible(childrenAreExpanded) && !SerializedProperty.EqualContents(prop, endProperty)) { EditorGUI.indentLevel = prop.depth + relIndent; position.height = EditorGUI.GetPropertyHeight(prop, null, false); EditorGUI.BeginChangeCheck(); childrenAreExpanded = ScriptAttributeUtility.GetHandler(prop).OnGUI(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); } }
public override void OnInspectorGUI() { if (initializeException != null) { ShowLoadErrorExceptionGUI(initializeException); ApplyRevertGUI(); return; } extraDataSerializedObject.Update(); var platforms = Compilation.CompilationPipeline.GetAssemblyDefinitionPlatforms(); using (new EditorGUI.DisabledScope(false)) { if (targets.Length > 1) { using (new EditorGUI.DisabledScope(true)) { var value = string.Join(", ", extraDataTargets.Select(t => t.name).ToArray()); EditorGUILayout.TextField(Styles.name, value, EditorStyles.textField); } } else { EditorGUILayout.PropertyField(m_AssemblyName, Styles.name); } GUILayout.Label(Styles.generalOptions, EditorStyles.boldLabel); EditorGUILayout.BeginVertical(GUI.skin.box); EditorGUILayout.PropertyField(m_AllowUnsafeCode, Styles.allowUnsafeCode); EditorGUILayout.PropertyField(m_AutoReferenced, Styles.autoReferenced); EditorGUILayout.PropertyField(m_OverrideReferences, Styles.overrideReferences); EditorGUILayout.EndVertical(); GUILayout.Space(10f); GUILayout.Label(Styles.defineConstraints, EditorStyles.boldLabel); m_DefineConstraints.DoLayoutList(); GUILayout.Label(Styles.references, EditorStyles.boldLabel); EditorGUILayout.BeginVertical(GUI.skin.box); EditorGUILayout.PropertyField(m_UseGUIDs, Styles.useGUIDs); EditorGUILayout.EndVertical(); m_ReferencesList.DoLayoutList(); if (extraDataTargets.Any(data => ((AssemblyDefinitionState)data).references != null && ((AssemblyDefinitionState)data).references.Any(x => x.asset == null))) { EditorGUILayout.HelpBox("The grayed out assembly references are missing and will not be referenced during compilation.", MessageType.Info); } if (m_OverrideReferences.boolValue && !m_OverrideReferences.hasMultipleDifferentValues) { GUILayout.Label(Styles.precompiledReferences, EditorStyles.boldLabel); UpdatePrecompiledReferenceListEntry(); m_PrecompiledReferencesList.DoLayoutList(); if (extraDataTargets.Any(data => ((AssemblyDefinitionState)data).precompiledReferences.Any(x => string.IsNullOrEmpty(x.path) && !string.IsNullOrEmpty(x.name)))) { EditorGUILayout.HelpBox("The grayed out assembly references are missing and will not be referenced during compilation.", MessageType.Info); } } GUILayout.Label(Styles.platforms, EditorStyles.boldLabel); EditorGUILayout.BeginVertical(GUI.skin.box); using (var change = new EditorGUI.ChangeCheckScope()) { EditorGUILayout.PropertyField(m_CompatibleWithAnyPlatform, Styles.anyPlatform); if (change.changed) { // Invert state include/exclude compatibility of states that have the opposite compatibility, // so all states are either include or exclude. var compatibleWithAny = m_CompatibleWithAnyPlatform.boolValue; var needToSwap = extraDataTargets.Cast <AssemblyDefinitionState>().Where(p => p.compatibleWithAnyPlatform != compatibleWithAny).ToList(); extraDataSerializedObject.ApplyModifiedProperties(); foreach (var state in needToSwap) { InversePlatformCompatibility(state); } extraDataSerializedObject.Update(); } } if (!m_CompatibleWithAnyPlatform.hasMultipleDifferentValues) { GUILayout.Label(m_CompatibleWithAnyPlatform.boolValue ? Styles.excludePlatforms : Styles.includePlatforms, EditorStyles.boldLabel); for (int i = 0; i < platforms.Length; ++i) { SerializedProperty property; if (i >= m_PlatformCompatibility.arraySize) { m_PlatformCompatibility.arraySize++; property = m_PlatformCompatibility.GetArrayElementAtIndex(i); property.boolValue = false; } else { property = m_PlatformCompatibility.GetArrayElementAtIndex(i); } EditorGUILayout.PropertyField(property, new GUIContent(platforms[i].DisplayName)); } EditorGUILayout.Space(); GUILayout.BeginHorizontal(); if (GUILayout.Button(Styles.selectAll)) { var prop = m_PlatformCompatibility.GetArrayElementAtIndex(0); var end = m_PlatformCompatibility.GetEndProperty(); do { prop.boolValue = true; }while (prop.Next(false) && !SerializedProperty.EqualContents(prop, end)); } if (GUILayout.Button(Styles.deselectAll)) { var prop = m_PlatformCompatibility.GetArrayElementAtIndex(0); var end = m_PlatformCompatibility.GetEndProperty(); do { prop.boolValue = false; }while (prop.Next(false) && !SerializedProperty.EqualContents(prop, end)); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); GUILayout.Space(10f); EditorGUILayout.BeginVertical(GUI.skin.box); GUILayout.Label(Styles.versionDefines, EditorStyles.boldLabel); m_VersionDefineList.DoLayoutList(); EditorGUILayout.EndVertical(); } extraDataSerializedObject.ApplyModifiedProperties(); ApplyRevertGUI(); }
// Given a serialized property, produce an object structure for JSON encoding of it. internal static Dictionary <string, object> WriteGenericSerializedProperty(SerializedProperty p) { var res = new Dictionary <string, object> { ["name"] = p.name, ["type"] = (int)p.propertyType }; switch (p.propertyType) { case SerializedPropertyType.Integer: case SerializedPropertyType.LayerMask: case SerializedPropertyType.Character: res["val"] = p.intValue; break; case SerializedPropertyType.Boolean: res["val"] = p.boolValue; break; case SerializedPropertyType.Float: res["val"] = p.floatValue; break; case SerializedPropertyType.String: res["val"] = p.stringValue; break; case SerializedPropertyType.ObjectReference: res["val"] = WriteCustom(new ObjectWrapper(p.objectReferenceValue)); break; case SerializedPropertyType.ArraySize: res["val"] = p.intValue; break; case SerializedPropertyType.AnimationCurve: res["val"] = WriteCustom(new AnimationCurveWrapper(p.animationCurveValue)); break; case SerializedPropertyType.Enum: res["val"] = WriteEnumProperty(p); break; case SerializedPropertyType.Bounds: res["val"] = WriteBounds(p.boundsValue); break; case SerializedPropertyType.Gradient: res["val"] = WriteCustom(new GradientWrapper(p.gradientValue)); break; case SerializedPropertyType.Quaternion: res["val"] = WriteQuaternion(p.quaternionValue); break; case SerializedPropertyType.Vector2Int: res["val"] = WriteVector2(p.vector2IntValue); break; case SerializedPropertyType.Vector3Int: res["val"] = WriteVector3(p.vector3IntValue); break; case SerializedPropertyType.RectInt: var ri = p.rectIntValue; res["val"] = WriteRect(new Rect(ri.x, ri.y, ri.width, ri.height)); break; case SerializedPropertyType.BoundsInt: var bi = p.boundsIntValue; res["val"] = WriteBounds(new Bounds(bi.center, bi.size)); break; // Copy/Paste of these for generic serialized properties is not implemented yet. case SerializedPropertyType.ExposedReference: break; case SerializedPropertyType.FixedBufferSize: break; case SerializedPropertyType.ManagedReference: break; default: if (p.isArray) { res["arraySize"] = p.arraySize; res["arrayType"] = p.arrayElementType; } if (p.hasChildren) { var children = new List <object>(); SerializedProperty chit = p.Copy(); var end = chit.GetEndProperty(); chit.Next(true); while (!SerializedProperty.EqualContents(chit, end)) { children.Add(WriteGenericSerializedProperty(chit)); if (!chit.Next(false)) { break; } } res["children"] = children; } break; } return(res); }
public float GetHeight(SerializedProperty property, GUIContent label, bool includeChildren) { float height = 0; if (m_DecoratorDrawers != null && !isCurrentlyNested) { foreach (DecoratorDrawer drawer in m_DecoratorDrawers) { height += drawer.GetHeight(); } } if (propertyDrawer != null) { // Retrieve drawer BEFORE increasing nesting. PropertyDrawer drawer = propertyDrawer; using (var nestingContext = IncrementNestingContext()) { height += drawer.GetPropertyHeightSafe(property.Copy(), label ?? EditorGUIUtility.TempContent(property.localizedDisplayName, tooltip)); } } else if (!includeChildren) { height += EditorGUI.GetSinglePropertyHeight(property, label); } else if (UseReorderabelListControl(property)) { ReorderableListWrapper reorderableList; string key = ReorderableListWrapper.GetPropertyIdentifier(property); // If collection doesn't have a ReorderableList assigned to it, create one and assign it if (!s_reorderableLists.TryGetValue(key, out reorderableList)) { reorderableList = new ReorderableListWrapper(property, label, true); s_reorderableLists[key] = reorderableList; } reorderableList.Property = property; height += s_reorderableLists[key].GetHeight(); return(height); } else { property = property.Copy(); // First property with custom label height += EditorGUI.GetSinglePropertyHeight(property, label); bool childrenAreExpanded = property.isExpanded && EditorGUI.HasVisibleChildFields(property); // Loop through all child properties var tc = EditorGUIUtility.TempContent(property.localizedDisplayName, tooltip); if (childrenAreExpanded) { SerializedProperty endProperty = property.GetEndProperty(); while (property.NextVisible(childrenAreExpanded) && !SerializedProperty.EqualContents(property, endProperty)) { height += ScriptAttributeUtility.GetHandler(property).GetHeight(property, tc, true); childrenAreExpanded = false; height += EditorGUI.kControlVerticalSpacing; } } } return(height); }
internal bool OnGUI(Rect position, SerializedProperty property, GUIContent label, bool includeChildren, Rect visibleArea) { TestInvalidateCache(); float oldLabelWidth, oldFieldWidth; float propHeight = position.height; position.height = 0; if (m_DecoratorDrawers != null && !isCurrentlyNested) { foreach (DecoratorDrawer decorator in 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 (propertyDrawer != null) { // Remember widths oldLabelWidth = EditorGUIUtility.labelWidth; oldFieldWidth = EditorGUIUtility.fieldWidth; // Draw with custom drawer - retrieve it BEFORE increasing nesting. PropertyDrawer drawer = propertyDrawer; using (var nestingContext = IncrementNestingContext()) { drawer.OnGUISafe(position, property.Copy(), label ?? EditorGUIUtility.TempContent(property.localizedDisplayName, tooltip)); } // Restore widths EditorGUIUtility.labelWidth = oldLabelWidth; EditorGUIUtility.fieldWidth = oldFieldWidth; return(false); } else { if (!includeChildren) { return(EditorGUI.DefaultPropertyField(position, property, label)); } if (UseReorderabelListControl(property)) { ReorderableListWrapper reorderableList; string key = ReorderableListWrapper.GetPropertyIdentifier(property); if (!s_reorderableLists.TryGetValue(key, out reorderableList)) { // Manual layout controls don't call GetHeight() method so we need to have a way to initialized list as we prepare to render it here reorderableList = new ReorderableListWrapper(property, label, true); s_reorderableLists[key] = reorderableList; } // Calculate visibility rect specifically for reorderable list as when applied for the whole serialized object, // it causes collapsed out of sight array elements appear thus messing up scroll-bar experience var screenPos = GUIUtility.GUIToScreenPoint(position.position); screenPos.y = Mathf.Clamp(screenPos.y, GUIView.current?.screenPosition.yMin ?? 0, GUIView.current?.screenPosition.yMax ?? Screen.height); Rect listVisibility = new Rect(screenPos.x, screenPos.y, GUIView.current?.screenPosition.width ?? Screen.width, GUIView.current?.screenPosition.height ?? Screen.height); listVisibility = GUIUtility.ScreenToGUIRect(listVisibility); reorderableList.Property = property; reorderableList.Draw(label, position, listVisibility, tooltip, includeChildren); return(!includeChildren && property.isExpanded); } // 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 = EditorGUI.DefaultPropertyField(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 handler = ScriptAttributeUtility.GetHandler(prop); EditorGUI.indentLevel = prop.depth + relIndent; position.height = handler.GetHeight(prop, null, UseReorderabelListControl(prop) && includeChildren); if (position.Overlaps(visibleArea)) { EditorGUI.BeginChangeCheck(); childrenAreExpanded = handler.OnGUI(position, prop, null, UseReorderabelListControl(prop)) && 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); } }
// Given an object structure from JSON encoding, apply that to a serialized property. internal static void ParseGenericSerializedProperty(SerializedProperty prop, Dictionary <string, object> obj) { if (prop == null) { return; } if (!obj.TryGetValue("name", out var oName)) { return; } var name = oName as string; if (string.IsNullOrEmpty(name)) { return; } if (!obj.TryGetValue("type", out var oType)) { return; } if (!(oType is long)) { return; } try { var propertyType = (SerializedPropertyType)Convert.ToInt32(oType); if (propertyType != prop.propertyType) { return; } obj.TryGetValue("val", out var oval); switch (propertyType) { case SerializedPropertyType.Integer: case SerializedPropertyType.LayerMask: case SerializedPropertyType.Character: prop.intValue = Convert.ToInt32(oval); break; case SerializedPropertyType.Boolean: prop.boolValue = Convert.ToBoolean(oval); break; case SerializedPropertyType.Float: prop.floatValue = Convert.ToSingle(oval); break; case SerializedPropertyType.String: prop.stringValue = Convert.ToString(oval); break; case SerializedPropertyType.ObjectReference: if (ParseCustom <ObjectWrapper>(Convert.ToString(oval), out var objectWrapper)) { prop.objectReferenceValue = objectWrapper.ToObject(); } break; case SerializedPropertyType.ArraySize: prop.arraySize = Convert.ToInt32(oval); break; case SerializedPropertyType.AnimationCurve: if (ParseCustom <AnimationCurveWrapper>(Convert.ToString(oval), out var animWrapper)) { prop.animationCurveValue = animWrapper.curve; } break; case SerializedPropertyType.Enum: ParseEnumProperty(Convert.ToString(oval), prop); break; case SerializedPropertyType.Bounds: if (ParseBounds(Convert.ToString(oval), out var boundsValue)) { prop.boundsValue = boundsValue; } break; case SerializedPropertyType.Gradient: if (ParseCustom <GradientWrapper>(Convert.ToString(oval), out var gradientWrapper)) { prop.gradientValue = gradientWrapper.gradient; UnityEditorInternal.GradientPreviewCache.ClearCache(); } break; case SerializedPropertyType.Quaternion: if (ParseQuaternion(Convert.ToString(oval), out var quaternionValue)) { prop.quaternionValue = quaternionValue; } break; case SerializedPropertyType.Vector2Int: if (ParseVector2(Convert.ToString(oval), out var v2Value)) { prop.vector2IntValue = new Vector2Int((int)v2Value.x, (int)v2Value.y); } break; case SerializedPropertyType.Vector3Int: if (ParseVector3(Convert.ToString(oval), out var v3Value)) { prop.vector3IntValue = new Vector3Int((int)v3Value.x, (int)v3Value.y, (int)v3Value.z); } break; case SerializedPropertyType.RectInt: if (ParseRect(Convert.ToString(oval), out var rectValue)) { prop.rectIntValue = new RectInt((int)rectValue.x, (int)rectValue.y, (int)rectValue.width, (int)rectValue.height); } break; case SerializedPropertyType.BoundsInt: if (ParseBounds(Convert.ToString(oval), out var biValue)) { prop.boundsIntValue = new BoundsInt( new Vector3Int((int)biValue.center.x, (int)biValue.center.y, (int)biValue.center.z), new Vector3Int((int)biValue.size.x, (int)biValue.size.y, (int)biValue.size.z)); } break; // Copy/Paste of these for generic serialized properties is not implemented yet. case SerializedPropertyType.FixedBufferSize: break; case SerializedPropertyType.ExposedReference: break; case SerializedPropertyType.ManagedReference: break; default: if (prop.isArray) { if (!obj.TryGetValue("arraySize", out var oArraySize)) { return; } if (!obj.TryGetValue("arrayType", out var oArrayType)) { return; } if (Convert.ToString(oArrayType) != prop.arrayElementType) { return; } prop.arraySize = Convert.ToInt32(oArraySize); } if (prop.hasChildren) { if (!obj.TryGetValue("children", out var oChildren)) { return; } if (!(oChildren is List <object> children)) { return; } SerializedProperty chit = prop.Copy(); var end = chit.GetEndProperty(); chit.Next(true); var index = 0; while (!SerializedProperty.EqualContents(chit, end) && index < children.Count) { if (!(children[index] is Dictionary <string, object> ch)) { return; } ParseGenericSerializedProperty(chit, ch); if (!chit.Next(false)) { break; } ++index; } } break; } } catch (InvalidCastException) { } }