public float GetHeight(SerializedProperty property, GUIContent label, bool includeChildren) { if (_visibleDrawer == null) this.Init(); property = property.Copy(); if (label == null) label = EditorHelper.TempContent(property.displayName); if (_visibleDrawer is IArrayHandlingPropertyDrawer || !property.isArray) { return _visibleDrawer.GetPropertyHeight(property, label); } else { float h = SPEditorGUI.GetSinglePropertyHeight(property, label); if (!includeChildren || !property.isExpanded) return h; h += EditorGUIUtility.singleLineHeight + 2f; for(int i = 0; i < property.arraySize; i++) { var pchild = property.GetArrayElementAtIndex(i); h += _visibleDrawer.GetPropertyHeight(pchild, EditorHelper.TempContent(pchild.displayName)) + 2f; } return h; } }
public static void CopyPropertyValue(SerializedProperty source, SerializedProperty dest) { source = source.Copy(); dest = dest.Copy(); var destSO = dest.serializedObject; if (source.hasVisibleChildren) { var sourceRoot = source.propertyPath; var destRoot = dest.propertyPath; while (source.NextVisible(true) && source.propertyPath.StartsWith(sourceRoot)) { if (source.propertyType == SerializedPropertyType.Generic) continue; var path = destRoot + source.propertyPath.Remove(0, sourceRoot.Length); var destProperty = destSO.FindProperty(path); SetPropertyValue(destProperty, GetPropertyValue(source)); } } else { if (dest.propertyPath == "m_RootOrder") { (dest.serializedObject.targetObject as Transform).SetSiblingIndex((int)GetPropertyValue(source)); } SetPropertyValue(dest, GetPropertyValue(source)); } }
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { position.height = EditorGUIUtility.singleLineHeight; property = property.Copy(); property.NextVisible(true); EditorGUI.PropertyField(position, property); position.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; property.NextVisible(true); EditorGUI.PropertyField(position, property); }
public static float GetPropertyHeight(UnityEditor.SerializedProperty property, bool includeChildren, GUIContent label) { var prop = property.Copy(); if (EditorUtilities.GetPropertyChildCount(prop) == 1 && prop.NextVisible(true) == true) { prop.isExpanded = true; return(UnityEditor.EditorGUI.GetPropertyHeight(prop, label, includeChildren)); } return(UnityEditor.EditorGUI.GetPropertyHeight(property, label, includeChildren)); }
internal static int GetChildrenCount(SerializedProperty property) { int num = 0; SerializedProperty x = property.Copy(); SerializedProperty endProperty = x.GetEndProperty(); while (!SerializedProperty.EqualContents(x, endProperty)) { num++; x.NextVisible(true); } return num; }
internal static int GetChildrenCount(SerializedProperty property) { int depth = property.depth; SerializedProperty property2 = property.Copy(); property2.NextVisible(true); int num2 = 0; while (property2.depth == (depth + 1)) { num2++; property2.NextVisible(false); } return num2; }
public static void ArrayProperty(string name, SerializedProperty prop) { SerializedProperty localProp = prop.Copy(); tk2dGuiUtility.LookLikeInspector(); if ( EditorGUILayout.PropertyField(localProp, new GUIContent(name)) ) { EditorGUI.indentLevel++; bool expanded = true; int depth = localProp.depth; while (localProp.NextVisible( expanded ) && depth < localProp.depth) { expanded = EditorGUILayout.PropertyField(localProp); } EditorGUI.indentLevel--; } }
internal static int GetChildrenCount(SerializedProperty property) { int depth = property.depth; SerializedProperty serializedProperty = property.Copy(); serializedProperty.NextVisible(true); int num = 0; while (serializedProperty.depth == depth + 1) { num++; serializedProperty.NextVisible(false); } return num; }
private static void ResetChildPropertyValues(SerializedProperty element) { if (!element.hasChildren) return; var childProperty = element.Copy(); int elementPropertyDepth = element.depth; bool enterChildren = true; while (childProperty.Next(enterChildren) && childProperty.depth > elementPropertyDepth) { enterChildren = false; ResetValue(childProperty); } }
/// <summary> /// Runs through all the child objects and return the one that matches the given name /// </summary> private static SerializedProperty GetChildProperty(SerializedProperty parent, string name) { SerializedProperty child = parent.Copy(); child.Next(true); do { if (child.name == name) return child; } while (child.Next(false)); return null; }
public static int GetPropertyChildCount(UnityEditor.SerializedProperty property) { var prop = property.Copy(); var enter = true; var depth = prop.depth; var count = 0; while (prop.NextVisible(enter) == true && prop.depth > depth) { ++count; enter = false; } return(count); }
/// <summary> /// Gets the height of the property. /// </summary> public override float GetPropertyHeight( SerializedProperty property, GUIContent label ) { float h = 0.0f; if( !heightIsChanged ) { return cacheHeight; } if( property.isArray ) { // header. h += c_fieldHeight; if( property.isExpanded ) { // size. { SerializedProperty propCopy = property.Copy(); propCopy.Next( true ); h += EditorGUI.GetPropertyHeight( propCopy ); } // elements. int size = property.arraySize; for( int i=0; i<size; ++i ) { SerializedProperty propElement = property.GetArrayElementAtIndex( i ); SerializedProperty propEnd = propElement.GetEndProperty(); // elements internal. do { h += EditorGUI.GetPropertyHeight( propElement, label, false ); } while( propElement.NextVisible( propElement.isExpanded ) && !SerializedProperty.EqualContents( propElement, propEnd ) ); } } } else { // helpbox. h += c_helpboxHeight; } cacheHeight = h; heightIsChanged = false; return h; }
private static void DoChildren(Rect position, SerializedProperty property) { float depth = (float) property.depth; position.height = 16f; ++EditorGUI.indentLevel; SerializedProperty property1 = property.Copy(); property1.NextVisible(true); while ((double) property1.depth == (double) depth + 1.0) { EditorGUI.PropertyField(position, property1); position.y += 16f; property1.NextVisible(false); } --EditorGUI.indentLevel; EditorGUILayout.Space(); }
private static void DoChildren(Rect position, SerializedProperty property) { float depth = property.depth; position.height = 16f; EditorGUI.indentLevel++; SerializedProperty property2 = property.Copy(); property2.NextVisible(true); while (property2.depth == (depth + 1f)) { EditorGUI.PropertyField(position, property2); position.y += 16f; property2.NextVisible(false); } EditorGUI.indentLevel--; EditorGUILayout.Space(); }
private static void DoChildren(Rect position, SerializedProperty property) { float num = (float)property.depth; position.height = 16f; EditorGUI.indentLevel++; SerializedProperty serializedProperty = property.Copy(); serializedProperty.NextVisible(true); while ((float)serializedProperty.depth == num + 1f) { EditorGUI.PropertyField(position, serializedProperty); position.y += 16f; serializedProperty.NextVisible(false); } EditorGUI.indentLevel--; EditorGUILayout.Space(); }
public bool OnGUI(Rect position, SerializedProperty property, GUIContent label, bool includeChildren) { if (_visibleDrawer == null) this.Init(); property = property.Copy(); if (label == null) label = EditorHelper.TempContent(property.displayName); if (_visibleDrawer is IArrayHandlingPropertyDrawer || !property.isArray) { _visibleDrawer.OnGUI(position, property, label); PropertyHandlerValidationUtility.AddAsHandled(property, this); return !includeChildren && property.isExpanded; } else { if (includeChildren && property.isExpanded) { var rect = new Rect(position.xMin, position.yMin, position.width, EditorGUIUtility.singleLineHeight); property.isExpanded = EditorGUI.Foldout(rect, property.isExpanded, label); EditorGUI.indentLevel++; rect = new Rect(rect.xMin, rect.yMax + 2f, rect.width, EditorGUIUtility.singleLineHeight); property.arraySize = Mathf.Max(0, EditorGUI.IntField(rect, "Size", property.arraySize)); var lbl = EditorHelper.TempContent(""); for (int i = 0; i < property.arraySize; i++) { var pchild = property.GetArrayElementAtIndex(i); lbl.text = pchild.displayName; var h = _visibleDrawer.GetPropertyHeight(pchild, lbl); rect = new Rect(rect.xMin, rect.yMax + 2f, rect.width, h); _visibleDrawer.OnGUI(rect, pchild, lbl); } EditorGUI.indentLevel--; PropertyHandlerValidationUtility.AddAsHandled(property, this); return true; } else { property.isExpanded = EditorGUI.Foldout(position, property.isExpanded, label); PropertyHandlerValidationUtility.AddAsHandled(property, this); return false; } } }
private void DrawArrayProperty(SerializedProperty prop) { EditorGUILayout.PropertyField(prop); if (prop.isExpanded) { EditorGUI.indentLevel++; SerializedProperty propChild = prop.Copy(); propChild.NextVisible(true); EditorGUILayout.PropertyField(propChild); bool arrayDiff = true; SerializedProperty preProp = null; if (prop.isInstantiatedPrefab) preProp = new SerializedObject(PrefabUtility.GetPrefabParent(prop.serializedObject.targetObject)).FindProperty(prop.name); for (int i = 0; i < prop.arraySize; i++) { SerializedProperty item = prop.GetArrayElementAtIndex(i); if (item.isArray) { DrawArrayProperty(item); } else { EditorGUILayout.PropertyField(item); if (prop.isInstantiatedPrefab) { if (preProp != null && preProp.arraySize == prop.arraySize && PropEquals(item, preProp.GetArrayElementAtIndex(i))) { item.prefabOverride = false; } else { arrayDiff = false; } } } } if(arrayDiff) { prop.prefabOverride = false; } EditorGUI.indentLevel--; } }
/// <summary> /// Copies value of <paramref name="sourceProperty"/> into <pararef name="destProperty"/>. /// </summary> /// <param name="destProperty">Destination property.</param> /// <param name="sourceProperty">Source property.</param> public static void CopyPropertyValue(SerializedProperty destProperty, SerializedProperty sourceProperty) { if (destProperty == null) throw new ArgumentNullException("destProperty"); if (sourceProperty == null) throw new ArgumentNullException("sourceProperty"); sourceProperty = sourceProperty.Copy(); destProperty = destProperty.Copy(); CopyPropertyValueSingular(destProperty, sourceProperty); if (sourceProperty.hasChildren) { int elementPropertyDepth = sourceProperty.depth; while (sourceProperty.Next(true) && destProperty.Next(true) && sourceProperty.depth > elementPropertyDepth) CopyPropertyValueSingular(destProperty, sourceProperty); } }
private static void DoChildren(Rect position, SerializedProperty property) { position.height = 16f; EditorGUI.indentLevel++; SerializedProperty x = property.Copy(); SerializedProperty endProperty = x.GetEndProperty(); x.NextVisible(true); while (!SerializedProperty.EqualContents(x, endProperty)) { EditorGUI.PropertyField(position, x); position.y += 16f; if (!x.NextVisible(false)) { break; } } EditorGUI.indentLevel--; EditorGUILayout.Space(); }
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(); }
private static void DoChildren(Rect position, SerializedProperty property) { float num = (float)property.depth; position.height = 16f; EditorGUI.indentLevel++; SerializedProperty serializedProperty = property.Copy(); serializedProperty.NextVisible(true); while ((float)serializedProperty.depth == num + 1f) { EditorGUI.PropertyField(position, serializedProperty); position.y += 16f; if (!serializedProperty.NextVisible(false)) { break; } } EditorGUI.indentLevel--; EditorGUILayout.Space(); }
public bool OnCurveAreaMouseDown(int button, Rect drawRect, Rect curveRanges) { if (button == 0) { ToggleCurveInEditor(); return(true); } if (button == 1) { SerializedProperty minCurve = GetMinCurve(); AnimationCurveContextMenu.Show(drawRect, maxCurve != null ? maxCurve.Copy() : null, minCurve != null ? minCurve.Copy() : null, scalar != null ? scalar.Copy() : null, curveRanges, m_Module.GetParticleSystemCurveEditor()); return(true); } return(false); }
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 static SerializedProperty GetChildProperty(SerializedProperty parent, string name) { //copy so we don't iterate original SerializedProperty copiedProperty = parent.Copy(); bool moreChildren = true; //step one level into child copiedProperty.Next(true); //iterate on all properties one level deep while (moreChildren) { //found the child we were looking for if (copiedProperty.name.Equals(name)) return copiedProperty; //move to the next property moreChildren = copiedProperty.Next(false); } //if we get here we didn't find it return null; }
public override void OnGUI(Rect _position, SerializedProperty _property, GUIContent _label) { string propertyName = NamedAttribute.PropertyName; if (string.IsNullOrEmpty(propertyName)) { char[] chars = _property.name.ToCharArray(); chars[0] = char.ToUpper(chars[0]); propertyName = new string(chars); } object prevValue = _property.Value(); SerializedProperty copy = _property.Copy(); EditorGUI.PropertyField(_position, copy); object obj = AttributeUtility.GetParentObjectFromProperty(_property); Type containerType = obj.GetType(); PropertyInfo p = containerType.GetProperty(propertyName); this.fieldInfo.SetValue(obj, prevValue); p.SetValue(obj, copy.Value(), null); }
static SerializedProperty FirstOrDefault(SerializedProperty prop, Predicate<SerializedProperty> predicate, bool descendIntoChildren = false) { while (prop.Next(descendIntoChildren)) { if (predicate(prop)) return prop.Copy(); } return null; }
public bool OnCurveAreaMouseDown(int button, Rect drawRect, Rect curveRanges) { bool result; if (button == 0) { this.ToggleCurveInEditor(); result = true; } else if (button == 1) { SerializedProperty serializedProperty = this.GetMinCurve(); AnimationCurveContextMenu.Show(drawRect, (this.maxCurve == null) ? null : this.maxCurve.Copy(), (serializedProperty == null) ? null : serializedProperty.Copy(), (this.scalar == null) ? null : this.scalar.Copy(), curveRanges, this.m_Module.GetParticleSystemCurveEditor()); result = true; } else { result = false; } return(result); }
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); } }
void ArrayGUI (SerializedProperty sp, string name) { EditorGUIUtility.LookLikeControls (100.0f, 40.0f); GUILayout.Space (4.0f); EditorGUILayout.BeginVertical ("box", GUILayout.MaxWidth(Screen.width)); int i = 0; int del = -1; SerializedProperty array = sp.Copy (); SerializedProperty size = null; bool first = true; while (true) { if (sp.propertyPath != name && !sp.propertyPath.StartsWith (name + ".")) break; bool child; EditorGUI.indentLevel = sp.depth; if (sp.depth == 1 && !first) { EditorGUILayout.BeginHorizontal (); if (GUILayout.Button ("", "OL Minus", GUILayout.Width (24.0f))) del = i; //GUILayout.Label ("" + i); child = EditorGUILayout.PropertyField (sp); GUI.enabled = i > 0; if (GUILayout.Button (manager.arrowUp, "ButtonLeft", GUILayout.Width (22.0f), GUILayout.Height(18.0f))) array.MoveArrayElement (i - 1, i); GUI.enabled = i < array.arraySize - 1; if (GUILayout.Button(manager.arrowDown, "ButtonRight", GUILayout.Width(22.0f), GUILayout.Height(18.0f))) array.MoveArrayElement (i + 1, i); ++i; GUI.enabled = true; EditorGUILayout.EndHorizontal (); } else if (sp.depth == 1) { first = false; size = sp.Copy (); EditorGUILayout.BeginHorizontal (); if (!size.hasMultipleDifferentValues && GUILayout.Button("", "OL Plus", GUILayout.Width(24.0f))) array.arraySize += 1; child = EditorGUILayout.PropertyField (sp); EditorGUILayout.EndHorizontal (); } else { child = EditorGUILayout.PropertyField(sp); } if (!sp.NextVisible (child)) break; } sp.Reset (); if (del != -1) array.DeleteArrayElementAtIndex (del); if (array.isExpanded && !size.hasMultipleDifferentValues) { EditorGUILayout.BeginHorizontal (); if (GUILayout.Button("", "OL Plus", GUILayout.Width(24.0f))) array.arraySize += 1; GUI.enabled = false; EditorGUILayout.PropertyField (array.GetArrayElementAtIndex (array.arraySize - 1), new GUIContent ("" + array.arraySize)); GUI.enabled = true; EditorGUILayout.EndHorizontal (); } EditorGUI.indentLevel = 0; EditorGUILayout.EndVertical (); EditorGUIUtility.LookLikeControls (170.0f, 80.0f); }
public static void SetByteArrayProperty(SerializedProperty property, byte[] byteArray) { if (!property.isArray || property.arraySize == 0) return; SerializedProperty iterator = property.Copy (); iterator.arraySize = byteArray.Length; while(iterator.name != "data") { iterator.Next(true); } for(int i = 0; i < byteArray.Length; i++) { iterator.intValue = byteArray[i]; iterator.Next(true); } }
private void copyGradient(SerializedProperty ss, SerializedProperty sd) { SerializedProperty gradient = ss.Copy(); SerializedProperty copyGrad = sd.Copy(); gradient.Next(true); copyGrad.Next(true); do { switch(gradient.propertyType) { case SerializedPropertyType.Color: copyGrad.colorValue = gradient.colorValue; break; case SerializedPropertyType.Integer: copyGrad.intValue = gradient.intValue; break; default: Debug.Log("CopyGradient: Unrecognized property type:" + gradient.propertyType); break; } gradient.Next(true); copyGrad.Next(true); } while(gradient.depth > 2); }
void DrawProperty(SerializedProperty property, int rootIdention, bool showChildren) { if (property.propertyType == SerializedPropertyType.ArraySize) return; property = property.Copy(); EditorGUI.indentLevel = rootIdention + property.depth + 1; GUILayout.BeginHorizontal(); PEPropertyHelper.PropertyFieldLayout(property, null, showChildren); if (targetProperty != null && targetProperty.serializedObject.targetObject == property.serializedObject.targetObject && property.propertyPath == targetProperty.propertyPath) { var rect = GUILayoutUtility.GetLastRect(); EditorGUI.DrawRect(rect, new Color(0, 1, 0, 0.1f)); } if (GUILayout.Button(GUIContent.none, this.plusButtonStyle, GUILayout.Width(30), GUILayout.Height(EditorGUIUtility.singleLineHeight))) OnPick(property, !Event.current.control && !Event.current.command); GUILayout.EndHorizontal(); EditorGUI.indentLevel = rootIdention; }
internal static Gradient DoGradientField(Rect position, int id, Gradient value, SerializedProperty property, bool hdr) { Event evt = Event.current; switch (evt.GetTypeForControl(id)) { case EventType.MouseDown: if (position.Contains(evt.mousePosition)) { if (evt.button == 0) { s_GradientID = id; GUIUtility.keyboardControl = id; Gradient gradient = property != null ? property.gradientValue : value; GradientPicker.Show(gradient, hdr); GUIUtility.ExitGUI(); } else if (evt.button == 1) { if (property != null) { GradientContextMenu.Show(property.Copy()); } // TODO: make work for Gradient value } } break; case EventType.Repaint: { Rect r2 = new Rect(position.x + 1, position.y + 1, position.width - 2, position.height - 2); // Adjust for box drawn on top if (property != null) { GradientEditor.DrawGradientSwatch(r2, property, Color.white); } else { GradientEditor.DrawGradientSwatch(r2, value, Color.white); } EditorStyles.colorPickerBox.Draw(position, GUIContent.none, id); break; } case EventType.ExecuteCommand: if (s_GradientID == id && evt.commandName == GradientPicker.GradientPickerChangedCommand) { GUI.changed = true; GradientPreviewCache.ClearCache(); HandleUtility.Repaint(); if (property != null) { property.gradientValue = GradientPicker.gradient; } return(GradientPicker.gradient); } break; case EventType.ValidateCommand: if (s_GradientID == id && evt.commandName == EventCommandNames.UndoRedoPerformed) { if (property != null) { GradientPicker.SetCurrentGradient(property.gradientValue); } GradientPreviewCache.ClearCache(); return(value); } break; case EventType.KeyDown: if (GUIUtility.keyboardControl == id && (evt.keyCode == KeyCode.Space || evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter)) { Event.current.Use(); Gradient gradient = property != null ? property.gradientValue : value; GradientPicker.Show(gradient, hdr); GUIUtility.ExitGUI(); } break; } return(value); }
public bool OnGUI(Rect position, SerializedProperty property, GUIContent label, bool includeChildren) { float num = position.height; position.height = 0f; if (this.m_DecoratorDrawers != null) { 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; }
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; }
// 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); } }
// 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); }
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); } }
private static void SetExpandedRecurse(SerializedProperty property, bool expanded) { SerializedProperty serializedProperty = property.Copy(); serializedProperty.isExpanded = expanded; int depth = serializedProperty.depth; while (serializedProperty.NextVisible(true) && serializedProperty.depth > depth) { if (serializedProperty.hasVisibleChildren) serializedProperty.isExpanded = expanded; } }
private static void DoPropertyFieldKeyboardHandling(SerializedProperty property) { if (Event.current.type == EventType.ExecuteCommand || Event.current.type == EventType.ValidateCommand) { if (GUIUtility.keyboardControl == EditorGUIUtility.s_LastControlID && (Event.current.commandName == "Delete" || Event.current.commandName == "SoftDelete")) { if (Event.current.type == EventType.ExecuteCommand) EditorGUI.s_PendingPropertyDelete = property.Copy(); Event.current.Use(); } if (GUIUtility.keyboardControl == EditorGUIUtility.s_LastControlID && Event.current.commandName == "Duplicate") { if (Event.current.type == EventType.ExecuteCommand) property.DuplicateCommand(); Event.current.Use(); } } EditorGUI.s_PendingPropertyKeyboardHandling = (SerializedProperty) null; }
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); }
private static IEnumerable<bool> CheckChildren(SerializedProperty mine, SerializedProperty theirs, GameObject mineParent, GameObject theirsParent) { bool enter = true; if(mine == null && theirs == null) yield break; if(mine == null || theirs == null) { yield return false; yield break; } SerializedProperty mTmp = mine.Copy(); SerializedProperty tTmp = theirs.Copy(); //I'm really not sure what's going on here. This seems to work differently for different types of properties while(mTmp.Next(enter)) { tTmp.Next(enter); enter = false; //Maybe we want this? if(mTmp.depth != mine.depth) //Once we're back in the same depth, we've gone too far break; bool equal = false; foreach (bool e in PropEqual(mTmp, tTmp, mineParent, theirsParent)) { yield return e; equal = e; } if(!equal) yield break; } yield return true; }
//プロパティを探す============================================================================= // 渡されたプロパティから名前が一致するプロパティを探し返します。 // 見つからない場合、Nullを返す //============================================================================================= private SerializedProperty FindProperty(SerializedProperty aProperty, string aName) { SerializedProperty nextProp = aProperty.Copy(); nextProp.Next(true); do { if(nextProp.name == aName) return nextProp; } while(nextProp.Next(false)); return null; }
// 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) { } }
public void RotationField(bool disabled) { Transform transform0 = targets[0] as Transform; Vector3 eulerAngles0 = transform0.GetLocalEulerAngles(transform0.rotationOrder); int differentRotationMask = 0b000; bool differentRotationOrder = false; for (int i = 1; i < targets.Length; i++) { Transform otherTransform = (targets[i] as Transform); if (differentRotationMask != 0b111) { Vector3 otherLocalEuler = otherTransform.GetLocalEulerAngles(otherTransform.rotationOrder); for (int j = 0; j < 3; j++) { if (otherLocalEuler[j] != eulerAngles0[j]) { differentRotationMask |= 1 << j; } } } differentRotationOrder |= otherTransform.rotationOrder != transform0.rotationOrder; } Rect r = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2)); GUIContent label = EditorGUI.BeginProperty(r, rotationContent, m_Rotation); m_EulerFloats[0].doubleVal = eulerAngles0.x; m_EulerFloats[1].doubleVal = eulerAngles0.y; m_EulerFloats[2].doubleVal = eulerAngles0.z; int id = GUIUtility.GetControlID(s_FoldoutHash, FocusType.Keyboard, r); if (AnimationMode.InAnimationMode() && transform0.rotationOrder != RotationOrder.OrderZXY) { string rotationLabel = differentRotationOrder ? "Mixed" : transform0.rotationOrder.ToString().Substring(RotationOrder.OrderXYZ.ToString().Length - 3); label.text = label.text + " (" + rotationLabel + ")"; } // Using manual 3 float fields here instead of MultiFloatField or Vector3Field // since we want to query expression validity of each individually, and // so that the label and the fields can be disabled separately, similar to // regular property fields. Also want to avoid superfluous label, which // creates a focus target even when there's no content (Case 953241). r = EditorGUI.MultiFieldPrefixLabel(r, id, label, 3); r.height = EditorGUIUtility.singleLineHeight; int eulerChangedMask = 0; using (new EditorGUI.DisabledScope(disabled)) { var eCount = m_EulerFloats.Length; float w = (r.width - (eCount - 1) * EditorGUI.kSpacingSubLabel) / eCount; Rect nr = new Rect(r) { width = w }; var prevWidth = EditorGUIUtility.labelWidth; var prevIndent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; for (int i = 0; i < m_EulerFloats.Length; i++) { EditorGUIUtility.labelWidth = EditorGUI.GetLabelWidth(s_XYZLabels[i]); EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = (differentRotationMask & (1 << i)) != 0; EditorGUI.FloatField(nr, s_XYZLabels[i], ref m_EulerFloats[i]); if (EditorGUI.EndChangeCheck() && m_EulerFloats[i].hasResult) { eulerChangedMask |= 1 << i; } if (Event.current.type == EventType.ContextClick && nr.Contains(Event.current.mousePosition)) { var childProperty = m_Rotation.Copy(); childProperty.Next(true); int childPropertyIndex = i; while (childPropertyIndex > 0) { childProperty.Next(false); childPropertyIndex--; } EditorGUI.DoPropertyContextMenu(childProperty); Event.current.Use(); } nr.x += w + EditorGUI.kSpacingSubLabel; } EditorGUIUtility.labelWidth = prevWidth; EditorGUI.indentLevel = prevIndent; } if (eulerChangedMask != 0) { eulerAngles0 = new Vector3( MathUtils.ClampToFloat(m_EulerFloats[0].doubleVal), MathUtils.ClampToFloat(m_EulerFloats[1].doubleVal), MathUtils.ClampToFloat(m_EulerFloats[2].doubleVal)); Undo.RecordObjects(targets, "Inspector"); // Generic undo title as remove duplicates will discard the name. Undo.SetCurrentGroupName(string.Format("Set Rotation")); for (var idx = 0; idx < targets.Length; ++idx) { var tr = targets[idx] as Transform; if (tr == null) { continue; } var trEuler = tr.GetLocalEulerAngles(tr.rotationOrder); // if we have any per-object expressions just entered, we need to evaluate // it for each object with their own individual input value for (int c = 0; c < 3; ++c) { if ((eulerChangedMask & (1 << c)) != 0) { if (m_EulerFloats[c].expression != null) { double trEulerComp = eulerAngles0[c]; if (m_EulerFloats[c].expression.Evaluate(ref trEulerComp, idx, targets.Length)) { trEuler[c] = MathUtils.ClampToFloat(trEulerComp); } } else { trEuler[c] = MathUtils.ClampToFloat(eulerAngles0[c]); } } } tr.SetLocalEulerAngles(trEuler, tr.rotationOrder); if (tr.parent != null) { tr.SendTransformChangedScale(); // force scale update, needed if tr has non-uniformly scaled parent. } } m_Rotation.serializedObject.SetIsDifferentCacheDirty(); } EditorGUI.showMixedValue = false; if (differentRotationOrder) { EditorGUILayout.HelpBox("Transforms have different rotation orders, keyframes saved will have the same value but not the same local rotation", MessageType.Warning); } EditorGUI.EndProperty(); }
protected void IterateSerializedProp(SerializedProperty property) { if (property.NextVisible(true)) { // Remember depth iteration started from int depth = property.Copy().depth; do { // If goes deeper than the iteration depth, get out if (property.depth != depth) break; DrawPropertySortableArray(property); } while (property.NextVisible(false)); } }