static bool ValidateThereIsARoot(SerializedProperty rootNameProperty, SerializedProperty boneList, bool doGUI) { string rootName = rootNameProperty.FindPropertyRelative("name").stringValue; bool rootExists = false; for (int i = 0; i < boneList.arraySize; i++) { string currentBone = boneList.GetArrayElementAtIndex(i).FindPropertyRelative("name").stringValue; if (currentBone == rootName) { rootExists = true; break; } } if (!rootExists) { if (boneList.arraySize == 1) { rootNameProperty.stringValue = boneList.GetArrayElementAtIndex(0).FindPropertyRelative("name").stringValue; } else { if (doGUI) { NaughtyEditorGUI.HelpBox_Layout("A bone must be selected as root bone.", MessageType.Error); } return(false); } } return(true); }
void ValidateNoDuplicateOverrides(ReorderableList list) { bool isValid = true; bonesWithOverride.Clear(); for (int i = 0; i < list.serializedProperty.arraySize; i++) { string bone = list.serializedProperty.GetArrayElementAtIndex(i).FindPropertyRelative("bone.name").stringValue; if (bonesWithOverride.Contains(bone)) { NaughtyEditorGUI.HelpBox_Layout($"Bone \"{bone}\" is duplicated.", MessageType.Warning, logToConsole: false); if (GUILayout.Button("Fix duplicate bone")) { list.serializedProperty.DeleteArrayElementAtIndex(i); i--; } isValid = false; } else { bonesWithOverride.Add(bone); } } if (!isValid) { SetIsNotValid(); } }
static bool ValidateNoEmptyNames(SerializedProperty boneList, bool doGUI) { bool hasEmptyNames = false; for (int i = 0; i < boneList.arraySize; i++) { string currentBone = boneList.GetArrayElementAtIndex(i).FindPropertyRelative("name").stringValue; if (string.IsNullOrEmpty(currentBone)) { hasEmptyNames = true; break; } } if (hasEmptyNames) { if (doGUI) { NaughtyEditorGUI.HelpBox_Layout("Empty bone names are not allowed.", MessageType.Error); } return(false); } else { return(true); } }
private void ShowQuickBuildTab() { EditorGUILayout.Space(); EditorGUILayout.HelpBox("Automatically sets build settings to get MVB " + "(minimum viable build) by including only necessary scenes.\n\n" + "Operates independently of the main build window. Settings are persistent and won't be picked up by git " + "(except Quick Load which is handled externally, so be sure to not commit that change).", MessageType.Info); NaughtyEditorGUI.PropertyField_Layout(mainStationProperty, false); mainStationScene = mainStationProperty.stringValue; ValidateMainStationScene(mainStationScene); EditorGUI.BeginChangeCheck(); var quickLoadLabel = new GUIContent( "Quick Load", "At runtime, skips the lobby scene and boots you straight into the map."); EditorGUILayout.Toggle(quickLoadLabel, QuickLoad.IsEnabled); if (EditorGUI.EndChangeCheck()) { QuickLoad.Toggle(); } EditorGUILayout.Space(); target = (BuildTarget)EditorGUILayout.EnumPopup("Target Platform", target); if (BuildPipeline.IsBuildTargetSupported(default, target) == false)
static bool ValidateNoDuplicateNames(SerializedProperty boneList, bool doGUI) { HashSet <string> duplicateSearchingSet = new HashSet <string>(); bool hasDuplicates = false; for (int i = 0; i < boneList.arraySize; i++) { if (!duplicateSearchingSet.Add(boneList.GetArrayElementAtIndex(i).FindPropertyRelative("name").stringValue)) { hasDuplicates = true; break; } } if (hasDuplicates) { if (doGUI) { NaughtyEditorGUI.HelpBox_Layout("There are duplicate bone names. This is not allowed.", MessageType.Error); } return(false); } else { return(true); } }
public static bool ValidateProfileField_Layout(SerializedProperty property, RagdollDefinition definition, bool isRequired) { string type = ReflectionUtility.GetField(property.serializedObject.targetObject, property.name).FieldType.Name; if (!property.objectReferenceValue) { if (isRequired) { NaughtyEditorGUI.HelpBox_Layout($"A {type} is required.", MessageType.Error); return(false); } else { return(true); } } else if (!(property.objectReferenceValue as RagdollProfile).IsValid) { NaughtyEditorGUI.HelpBox_Layout($"The assigned {type} is not valid.", MessageType.Error); return(false); } else if (definition != null && (property.objectReferenceValue as RagdollProfile).IsCompatibleWith(definition) != definition) { NaughtyEditorGUI.HelpBox_Layout($"The bound RagdollDefinition and the {type}'s RagdollDefinition are incompatible.", MessageType.Error); return(false); } else { return(true); } }
protected void DrawBaseProperties(params string[] excludedNames) { EditorGUILayout.Space(); using (new EditorGUI.IndentLevelScope(1)) { foreach (var prop in baseProperties) { if (excludedNames.Any(o => o == prop.name)) { continue; } if (isCallableArray(prop)) { reorderableLists[GetPropertyKeyName(prop)].DoLayoutList(); } else { NaughtyEditorGUI.PropertyField_Layout(prop, true); } } } DrawButtons(); }
public override void OnInspectorGUI() { serializedObject.Update(); RagdollProfileEditorUtility.DrawDefinitionField_Layout(definition, true); hasValidDefinition = RagdollProfileEditorUtility.IsValid(definition); if (hasValidDefinition) { RagdollProfileEditorUtility.RefreshBoneDictionaryKeys(bindingsDictionary, definition); NaughtyEditorGUI.BeginBoxGroup_Layout("Bindings"); EditorGUI.BeginDisabledGroup(Application.isPlaying); DrawBindingFields(); DrawAutoCompleteButton(); EditorGUI.EndDisabledGroup(); NaughtyEditorGUI.EndBoxGroup_Layout(); ValidateNoDuplicateJoints(); ValidateNoUnassignedBones(); } serializedObject.ApplyModifiedProperties(); }
protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(rect, label, property); System.Type propertyType = PropertyUtility.GetPropertyType(property); if (typeof(ScriptableObject).IsAssignableFrom(propertyType)) { ScriptableObject scriptableObject = property.objectReferenceValue as ScriptableObject; if (scriptableObject == null) { EditorGUI.PropertyField(rect, property, label, false); } else { // Draw a foldout Rect foldoutRect = new Rect() { x = rect.x, y = rect.y, width = EditorGUIUtility.labelWidth, height = EditorGUIUtility.singleLineHeight }; property.isExpanded = EditorGUI.Foldout(foldoutRect, property.isExpanded, label, toggleOnLabelClick: true); // Draw the scriptable object field float indentLength = NaughtyEditorGUI.GetIndentLength(rect); float labelWidth = EditorGUIUtility.labelWidth - indentLength + NaughtyEditorGUI.HorizontalSpacing; Rect propertyRect = new Rect() { x = rect.x + labelWidth, y = rect.y, width = rect.width - labelWidth, height = EditorGUIUtility.singleLineHeight }; EditorGUI.BeginChangeCheck(); property.objectReferenceValue = EditorGUI.ObjectField(propertyRect, GUIContent.none, property.objectReferenceValue, propertyType, false); if (EditorGUI.EndChangeCheck()) { property.serializedObject.ApplyModifiedProperties(); } // Draw the child properties if (property.isExpanded) { DrawChildProperties(rect, property); } } } else { string message = $"{typeof(ExpandableAttribute).Name} can only be used on scriptable objects"; DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning); } EditorGUI.EndProperty(); }
public override void OnGUI(Rect position) { Rect rect = EditorGUI.IndentedRect(position); rect.y += EditorGUIUtility.singleLineHeight / 3.0f; HorizontalLineAttribute lineAttr = (HorizontalLineAttribute)attribute; NaughtyEditorGUI.HorizontalLine(rect, lineAttr.Height, lineAttr.Color.GetColor()); }
void DrawPowerProfile() { NaughtyEditorGUI.BeginBoxGroup_Layout("Power Settings"); for (int i = 0; i < settingsKeys.arraySize; i++) { DrawPowerSetting(settingsKeys.GetArrayElementAtIndex(i), settingsValues.GetArrayElementAtIndex(i)); } NaughtyEditorGUI.EndBoxGroup_Layout(); }
protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label) { if (property.isArray) { string key = GetPropertyKeyName(property); ReorderableList reorderableList = null; if (!_reorderableListsByPropertyName.ContainsKey(key)) { reorderableList = new ReorderableList(property.serializedObject, property, true, true, true, true) { drawHeaderCallback = (Rect r) => { EditorGUI.LabelField(r, string.Format("{0}: {1}", label.text, property.arraySize), GetLabelStyle()); HandleDragAndDrop(r, reorderableList); }, drawElementCallback = (Rect r, int index, bool isActive, bool isFocused) => { SerializedProperty element = property.GetArrayElementAtIndex(index); r.y += 1.0f; r.x += 10.0f; r.width -= 10.0f; EditorGUI.PropertyField(new Rect(r.x, r.y, r.width, EditorGUIUtility.singleLineHeight), element, true); }, elementHeightCallback = (int index) => { return(EditorGUI.GetPropertyHeight(property.GetArrayElementAtIndex(index)) + 4.0f); } }; _reorderableListsByPropertyName[key] = reorderableList; } reorderableList = _reorderableListsByPropertyName[key]; if (rect == default) { reorderableList.DoLayoutList(); } else { reorderableList.DoList(rect); } } else { string message = typeof(ReorderableListAttribute).Name + " can be used only on arrays or lists"; NaughtyEditorGUI.HelpBox_Layout(message, MessageType.Warning, context: property.serializedObject.targetObject); EditorGUILayout.PropertyField(property, true); } }
void DrawFactors() { NaughtyEditorGUI.BeginBoxGroup_Layout("Distribution"); for (int i = 0; i < factorsKeys.arraySize; i++) { DrawFactor(factorsKeys.GetArrayElementAtIndex(i), factorsValues.GetArrayElementAtIndex(i)); } NaughtyEditorGUI.EndBoxGroup_Layout(); }
void ValidateNoUnassignedBones() { for (int i = 0; i < values.arraySize; i++) { if (values.GetArrayElementAtIndex(i).objectReferenceValue == null) { NaughtyEditorGUI.HelpBox_Layout("All bones must be bound to a ConfigurableJoint.", MessageType.Error); return; } } }
public override void OnGUI(Rect rect) { InfoBoxAttribute infoBoxAttribute = (InfoBoxAttribute)attribute; float indentLength = NaughtyEditorGUI.GetIndentLength(rect); Rect infoBoxRect = new Rect( rect.x + indentLength, rect.y, rect.width - indentLength, GetHelpBoxHeight()); DrawInfoBox(infoBoxRect, infoBoxAttribute.Text, infoBoxAttribute.Type); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.PropertyField(position, property, label, true); Rect controlRect = EditorGUILayout.GetControlRect(); if (controlRect != null) { controlRect.height = 2; controlRect.y += controlRect.height * 4; NaughtyEditorGUI.HorizontalLine(controlRect, 2.0f, Gray); } }
protected void DrawButtons() { if (_methods.Any()) { EditorGUILayout.Space(); EditorGUILayout.LabelField("Buttons", GetHeaderGUIStyle()); NaughtyEditorGUI.HorizontalLine( EditorGUILayout.GetControlRect(false), HorizontalLineAttribute.DefaultHeight, HorizontalLineAttribute.DefaultColor.GetColor()); foreach (var method in _methods) { NaughtyEditorGUI.Button(serializedObject.targetObject, method); } } }
protected void DrawNativeProperties() { if (_nativeProperties.Any()) { EditorGUILayout.Space(); EditorGUILayout.LabelField("Native Properties", GetHeaderGUIStyle()); NaughtyEditorGUI.HorizontalLine( EditorGUILayout.GetControlRect(false), HorizontalLineAttribute.DefaultHeight, HorizontalLineAttribute.DefaultColor.GetColor()); foreach (var property in _nativeProperties) { NaughtyEditorGUI.NativeProperty_Layout(serializedObject.targetObject, property); } } }
public static void DrawDefinitionField_Layout(SerializedProperty definition, bool isRequired) { EditorGUI.BeginDisabledGroup(Application.isPlaying); EditorGUILayout.PropertyField(definition); EditorGUI.EndDisabledGroup(); if (isRequired && !HasDefinition(definition)) { NaughtyEditorGUI.HelpBox_Layout("A RagdollDefinition must be assigned.", MessageType.Error); } else if (HasDefinition(definition) && !IsValid(definition)) { NaughtyEditorGUI.HelpBox_Layout("The Ragdoll Definition is invalid.", MessageType.Error); } }
protected void DrawNonSerializedFields() { if (_nonSerializedFields.Any()) { EditorGUILayout.Space(); EditorGUILayout.LabelField("Non-Serialized Fields", GetHeaderGUIStyle()); NaughtyEditorGUI.HorizontalLine( EditorGUILayout.GetControlRect(false), HorizontalLineAttribute.DefaultHeight, HorizontalLineAttribute.DefaultColor.GetColor()); foreach (var field in _nonSerializedFields) { NaughtyEditorGUI.NonSerializedField_Layout(serializedObject.targetObject, field); } } }
void WarnAgainstUnstablePositionMatchingParameters() { bool hasUnstableSettings = false; if (!PositionMatchingParametersAreStable(serializedObject.FindProperty("globalPositionAlpha").floatValue, serializedObject.FindProperty("globalPositionDampingRatio").floatValue)) { hasUnstableSettings = true; } for (int i = 0; i < positionMatchingOverridesList.serializedProperty.arraySize && !hasUnstableSettings; i++) { if (!PositionMatchingParametersAreStable( positionMatchingOverridesList.serializedProperty.GetArrayElementAtIndex(i).FindPropertyRelative("alpha").floatValue, positionMatchingOverridesList.serializedProperty.GetArrayElementAtIndex(i).FindPropertyRelative("dampingRatio").floatValue)) { hasUnstableSettings = true; } } if (hasUnstableSettings) { NaughtyEditorGUI.HelpBox_Layout($"Settings where (alpha + dampingRatio > {MAX_STABLE_ALPHA_PLUS_DAMPING}) are often unstable. Consider lowering the parameters." , MessageType.Warning, logToConsole: false); if (GUILayout.Button("Fix unstable parameters")) { FixUnstableParameters(serializedObject.FindProperty("globalPositionAlpha"), serializedObject.FindProperty("globalPositionDampingRatio")); for (int i = 0; i < positionMatchingOverridesList.serializedProperty.arraySize; i++) { FixUnstableParameters( positionMatchingOverridesList.serializedProperty.GetArrayElementAtIndex(i).FindPropertyRelative("alpha"), positionMatchingOverridesList.serializedProperty.GetArrayElementAtIndex(i).FindPropertyRelative("dampingRatio") ); } } } void FixUnstableParameters(SerializedProperty alpha, SerializedProperty dampingRatio) { if (!PositionMatchingParametersAreStable(alpha.floatValue, dampingRatio.floatValue)) { alpha.floatValue = MAX_STABLE_ALPHA_PLUS_DAMPING - dampingRatio.floatValue; } } }
static bool ValidateNotEmpty(SerializedProperty boneList, bool doGUI) { bool isEmpty = boneList.arraySize == 0; if (isEmpty) { if (doGUI) { NaughtyEditorGUI.HelpBox_Layout("At least 1 bone is required.", MessageType.Error); } return(false); } else { return(true); } }
protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label) { if (property.hasChildren) { InlineAttribute attribute = PropertyUtility.GetAttribute <InlineAttribute>(property); if (attribute.ShowHeaderAndBox) { rect.position += new Vector2(0, EditorGUIUtility.singleLineHeight * 0.2f); EditorGUI.LabelField(rect, label, EditorStyles.boldLabel); NaughtyEditorGUI.BeginBoxGroup_Layout(); } //Move to first child SerializedProperty child = property.Copy(); child.Next(true); SerializedProperty endProperty = property.GetEndProperty(true); bool enterChildren; if (attribute.ShowHeaderAndBox) { enterChildren = EditorGUILayout.PropertyField(child); } else { enterChildren = EditorGUI.PropertyField(rect, child); } while (child.Next(enterChildren) && !SerializedProperty.EqualContents(child, endProperty)) { enterChildren = EditorGUILayout.PropertyField(child); } if (attribute.ShowHeaderAndBox) { NaughtyEditorGUI.EndBoxGroup_Layout(); } } else { EditorGUILayout.PropertyField(property); NaughtyEditorGUI.HelpBox_Layout("Can't use [Inline] on a property with no children.", MessageType.Warning); } }
public override void OnInspectorGUI_PingArea() { serializedObject.Update(); bool excludedRigManager = GameplayIngredientsSettings.currentSettings.excludedeManagers.Any(s => s == "RigManager"); if (excludedRigManager) { EditorGUILayout.HelpBox("This Rig depends on the Rig Manager which is excluded in your Gameplay Ingredients Settings. This rig component will be inactive unless the manager is not excluded.", MessageType.Error, true); if (GUILayout.Button("Open Settings")) { Selection.activeObject = GameplayIngredientsSettings.currentSettings; } } EditorGUI.BeginDisabledGroup(excludedRigManager); EditorGUI.BeginChangeCheck(); DrawBreadCrumb("Rig", color, () => { GUILayout.Label(ObjectNames.NicifyVariableName(serializedObject.targetObject.GetType().Name), GUILayout.ExpandWidth(true)); OpenIngredientsExplorerButton(serializedObject.targetObject as Rig); }); using (new GUILayout.VerticalScope(EditorStyles.helpBox, GUILayout.ExpandWidth(true))) { GUILayout.Label("Rig Update Properties", EditorStyles.boldLabel); using (new EditorGUI.IndentLevelScope(1)) { NaughtyEditorGUI.PropertyField_Layout(m_UpdateMode, true); NaughtyEditorGUI.PropertyField_Layout(m_RigPriority, true); } } DrawBaseProperties(); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); } EditorGUI.EndDisabledGroup(); }
protected void DrawBaseProperties(params string[] excludedNames) { EditorGUILayout.Space(); using (new EditorGUI.IndentLevelScope(1)) { foreach (var prop in baseProperties) { if (excludedNames.Any(o => o == prop.name)) { continue; } NaughtyEditorGUI.PropertyField_Layout(prop, true); } } DrawButtons(); }
void WarnAgainstPositionWithoutRotation() { bool hasInvalidBones = false; if (serializedObject.FindProperty("globalPositionAlpha").floatValue > 0 && serializedObject.FindProperty("globalRotationAlpha").floatValue <= 0) { hasInvalidBones = true; } if (!hasInvalidBones) { bonesWithNonZeroPositionMatchingOverride.Clear(); SerializedProperty posOverrides = serializedObject.FindProperty("positionMatchingOverrides"); SerializedProperty rotOverrides = serializedObject.FindProperty("rotationMatchingOverrides"); for (int i = 0; i < posOverrides.arraySize; i++) { SerializedProperty posOverride = posOverrides.GetArrayElementAtIndex(i); if (posOverride.FindPropertyRelative("alpha").floatValue > 0) { bonesWithNonZeroPositionMatchingOverride.Add(posOverride.FindPropertyRelative("bone.name").stringValue); } } for (int i = 0; i < rotOverrides.arraySize; i++) { SerializedProperty rotOverride = rotOverrides.GetArrayElementAtIndex(i); bool boneHasPosOverride = bonesWithNonZeroPositionMatchingOverride.Contains(rotOverride.FindPropertyRelative("bone.name").stringValue); if (boneHasPosOverride && rotOverride.FindPropertyRelative("alpha").floatValue <= 0) { hasInvalidBones = true; break; } } } if (hasInvalidBones) { NaughtyEditorGUI.HelpBox_Layout("Position Matching with no Rotation Matching can produce horrifying results. \n" + "To avoid this, make sure that no bone has a Position Alpha over 0 and a Rotation Alpha of 0.", MessageType.Warning, logToConsole: false); } }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { MinMaxRange.SliderAttribute attribute = PropertyUtility.GetAttribute <MinMaxRange.SliderAttribute>(property); if (attribute != null) { Draw(position, property, attribute.min, attribute.max, label); } else { EditorGUI.PropertyField(position, property, label); if (property.isExpanded) { EditorGUI.indentLevel++; NaughtyEditorGUI.HelpBox_Layout("MinMaxRange needs a [MinMaxRange.Slider(min, max)] attribute for the fancy editor.", MessageType.Info); EditorGUI.indentLevel--; } } }
public void DrawDefaultPropertyAndHelpBox(Rect rect, SerializedProperty property, string message, MessageType messageType) { float indentLength = NaughtyEditorGUI.GetIndentLength(rect); Rect helpBoxRect = new Rect( rect.x + indentLength, rect.y, rect.width - indentLength, GetHelpBoxHeight()); NaughtyEditorGUI.HelpBox(helpBoxRect, message, MessageType.Warning, context: property.serializedObject.targetObject); Rect propertyRect = new Rect( rect.x, rect.y + GetHelpBoxHeight(), rect.width, GetPropertyHeight(property)); EditorGUI.PropertyField(propertyRect, property, true); }
public override void OnInspectorGUI_PingArea() { serializedObject.Update(); EditorGUI.BeginChangeCheck(); DrawBreadCrumb("Action", color, () => { NaughtyEditorGUI.PropertyField_Layout(m_Name, true); OpenIngredientsExplorerButton(serializedObject.targetObject as ActionBase); }); DrawBaseProperties("Name"); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); } }
void ValidateNoDuplicatePairs() { bool hasDuplicates = false; duplicatePairValidationSet.Clear(); foreach (SerializedProperty pair in bonePairsList.serializedProperty) { if (!duplicatePairValidationSet.Add(CreateBonePairFromPairProperty(pair))) { hasDuplicates = true; break; } } if (hasDuplicates) { NaughtyEditorGUI.HelpBox_Layout("There are duplicate pairs.", MessageType.Warning); SetIsNotValid(); if (GUILayout.Button("Fix")) { Fix(); } } void Fix() { duplicatePairValidationSet.Clear(); for (int i = 0; i < bonePairsList.serializedProperty.arraySize; i++) { SerializedProperty pair = bonePairsList.serializedProperty.GetArrayElementAtIndex(i); if (!duplicatePairValidationSet.Add(CreateBonePairFromPairProperty(pair))) { bonePairsList.serializedProperty.DeleteArrayElementAtIndex(i); i--; } } } }