public void ShowTypes() { GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); bShowTypes = EditorGUILayout.Foldout(bShowTypes, "Additional Indexed Types"); GUILayout.EndHorizontal(); if (bShowTypes) { GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); // Draw and handle the Drag/Drop GUILayout.Space(20); Rect dropTypeArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true)); GUI.Box(dropTypeArea, "Drag a single type here to start indexing that type."); GUILayout.Space(20); DropAreaType(dropTypeArea); foreach (string s in UAI.IndexedTypeNames) { System.Type CurrentType = System.Type.GetType(s); GUILayout.BeginHorizontal(EditorStyles.textField); GUILayout.Label(CurrentType.ToString(), GUILayout.MinWidth(240)); if (GUILayout.Button("-", GUILayout.Width(20.0f))) { RemovedTypes.Add(CurrentType); } GUILayout.EndHorizontal(); } GUIHelper.EndVerticalPadded(10); } }
private void DrawUpgradeTools() { if (converterControllerProp.objectReferenceValue == null) { var upgradeRect = EditorGUILayout.GetControlRect(); var prevColor = GUI.color; GUI.color = new Color(1, 0.9f, 0, 1); //GUIHelper.ToolbarStyleFoldout(upgradeRect, "Upgrade Available!", ref _upgradeExpanded, null, foldoutTipStyle); GUIHelper.ToolbarStyleHeader(upgradeRect, new GUIContent("Upgrade Available!"), new string[0], ref _upgradeExpanded, null, EditorStyles.boldLabel); _upgradeExpanded = true; GUI.color = prevColor; GUIHelper.BeginVerticalPadded(3, new Color(0.75f, 0.875f, 1f, 0.3f)); EditorGUILayout.HelpBox("Please click the 'Upgrade' button to upgrade this ConverterBehaviour into a ConverterController asset that is better suited for Unity 2018+", MessageType.Info); var moreRect = EditorGUILayout.GetControlRect(); GUIHelper.ToolbarStyleFoldout(moreRect, "More Info", ref upgradeInfoExpanded, GUIStyle.none); if (upgradeInfoExpanded) { EditorGUILayout.HelpBox(upgradeInfo1, MessageType.None); EditorGUILayout.HelpBox(upgradeInfo2, MessageType.None); EditorGUILayout.HelpBox(upgradeInfo3, MessageType.None); } GUILayout.BeginHorizontal(); GUILayout.Space(10); if (GUILayout.Button("Upgrade")) { DoUpgrade(); } GUILayout.Space(10); GUILayout.EndHorizontal(); EditorGUILayout.Space(); GUIHelper.EndVerticalPadded(3); } }
public void DrawLegacySkeletonModifiersGUI() { if (!initialized) { Debug.LogError("Please initialize an instance of LegacySkeletonModifierListDrawer before trying to use it!"); return; } var skeletonModifiers = serializedObject.FindProperty("_skeletonModifiers"); GUIHelper.BeginVerticalPadded(3, new Color(0.75f, 0.875f, 1f, 0.3f)); EditorGUI.indentLevel++; skeletonModifiers.isExpanded = EditorGUILayout.Foldout(skeletonModifiers.isExpanded, "Skeleton Modifiers"); if (skeletonModifiers.isExpanded) { if (!minimalMode) { EditorGUILayout.HelpBox("TIP: Setting up your DNA Converter's Skeleton Modifiers is much easier if you use the 'DNA Converter Bahaviour Customizer' scene as it can automatically populate the list of available bones with the ones in the generated Avatar's skeleton.", MessageType.Info); } skeletonModifiersInfoExpanded = EditorGUILayout.Foldout(skeletonModifiersInfoExpanded, "INFO"); if (skeletonModifiersInfoExpanded) { EditorGUILayout.HelpBox(_skelModsTip, MessageType.Info); } //If dnaNames is null or empty show a warning //UMA2.8+ OBSOLETE /*bool showDNANamesWarning = false; * if (skeletonModifiers.serializedObject.FindProperty("dnaAsset").objectReferenceValue == null) * showDNANamesWarning = true; * else if ((skeletonModifiers.serializedObject.FindProperty("dnaAsset").objectReferenceValue as DynamicUMADnaAsset).Names.Length == 0) * showDNANamesWarning = true; * if (showDNANamesWarning) * EditorGUILayout.HelpBox("You need to have your DNA Names set up above in order for the Skeleton Modifiers to make any modifications", MessageType.Warning);*/ EditorGUI.indentLevel++; extraSkelAddDelOptsExpanded = EditorGUILayout.Foldout(extraSkelAddDelOptsExpanded, "Add/Delete Modifier Options"); EditorGUI.indentLevel--; if (extraSkelAddDelOptsExpanded) { DrawLegacySkeletonModifiersAddDeleteTools(skeletonModifiers); } DrawLegacySkeletonModifiersAddNew(skeletonModifiers); EditorGUILayout.Space(); DrawLegacySkeletonModifiersList(skeletonModifiers); DrawLegacySkeletonModifiersResetStartingValues(skeletonModifiers); EditorGUILayout.Space(); } EditorGUI.indentLevel--; GUIHelper.EndVerticalPadded(3); serializedObject.ApplyModifiedProperties(); }
private void BeginVerticalPadded() { if (EditorGUIUtility.isProSkin) { GUIHelper.BeginVerticalPadded(10, new Color(1.3f, 1.4f, 1.5f)); } else { GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); } }
public void ShowArray(System.Type CurrentType) { Dictionary <string, UMAAssetIndexer.AssetItem> TypeDic = UAI.GetAssetDictionary(CurrentType); GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); Toggles[CurrentType] = EditorGUILayout.Foldout(Toggles[CurrentType], CurrentType.Name + ": " + TypeDic.Count + " Item(s)"); GUILayout.EndHorizontal(); if (Toggles[CurrentType]) { GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); GUILayout.BeginHorizontal(); GUILayout.Label("Sorted By: " + UMAAssetIndexer.SortOrder, GUILayout.MaxWidth(160)); foreach (string s in UMAAssetIndexer.SortOrders) { if (GUILayout.Button(s, GUILayout.Width(80))) { UMAAssetIndexer.SortOrder = s; } } GUILayout.EndHorizontal(); List <UMAAssetIndexer.AssetItem> Items = new List <UMAAssetIndexer.AssetItem>(); Items.AddRange(TypeDic.Values); Items.Sort(); foreach (UMAAssetIndexer.AssetItem ai in Items) { GUILayout.BeginHorizontal(EditorStyles.textField); string lblVal = ai.ToString(UMAAssetIndexer.SortOrder); if (GUILayout.Button(lblVal /* ai._Name + " (" + ai._AssetBaseName + ")" */, EditorStyles.label)) { EditorGUIUtility.PingObject(AssetDatabase.LoadMainAssetAtPath(ai._Path)); } if (GUILayout.Button("-", GUILayout.Width(20.0f))) { DeletedDuringGUI.Add(ai); } GUILayout.EndHorizontal(); } GUIHelper.EndVerticalPadded(10); } }
private void DrawBonePoseCreationTools() { if (thisDDCC.targetUMA.umaData.skeleton != null) { GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f, 0.3f)); EditorGUILayout.LabelField("Create Poses from Current DNA state", EditorStyles.boldLabel); EditorGUILayout.HelpBox("Create bone poses from Avatar's current dna modified state. Applies the pose and sets DNA values back to 0.", MessageType.None); EditorGUILayout.HelpBox("Tip: Ensure all modifications you do not want included are turned off/set to default. In particular you will probably want to set 'Overall Modifiers' scale to 1 if you are planning to apply this in addition to the Pose later on.", MessageType.Info); EditorGUILayout.HelpBox("Smaller margin of error equals greater accuracy but creates more poses to apply on DNA Update.", MessageType.None); if (thisDDCC != null) { //[Range(0.000005f, 0.0005f)] EditorGUI.BeginChangeCheck(); var thisAccuracy = EditorGUILayout.Slider(new GUIContent("Margin Of Error", "The smaller the margin of error, the more accurate the Pose will be, but it will also have more bonePoses to apply when DNA is updated"), thisDDCC.bonePoseAccuracy * 1000, 0.5f, 0.005f); if (EditorGUI.EndChangeCheck()) { thisDDCC.bonePoseAccuracy = thisAccuracy / 1000; GUI.changed = false; } } createBonePoseAssetName = EditorGUILayout.TextField("New Bone Pose Name", createBonePoseAssetName); EditorGUILayout.HelpBox("Should the pose be applied and the dna values be reset to 0?", MessageType.None); applyAndResetOnCreateBP = EditorGUILayout.Toggle("Apply and Reset", applyAndResetOnCreateBP); GUILayout.BeginHorizontal(); GUILayout.Space(20); if (GUILayout.Button(/*createFromDnaButR, */ "Create New BonePose Asset")) { if (thisDDCC != null) { if (thisDDCC.CreateBonePosesFromCurrentDna(createBonePoseAssetName, applyAndResetOnCreateBP)) { serializedObject.Update(); createBonePoseAssetName = ""; //this needs to repaint the plugins because their height of the reorderable list has changed now //cant figure out how to do that though } } } GUILayout.Space(20); GUILayout.EndHorizontal(); GUIHelper.EndVerticalPadded(10); } }
private void DrawUpdateTools() { var upgradeRect = EditorGUILayout.GetControlRect(); GUIHelper.ToolbarStyleHeader(upgradeRect, new GUIContent("Update Tools"), new string[0], ref _upgradeExpanded, null, EditorStyles.boldLabel); _upgradeExpanded = true; GUIHelper.BeginVerticalPadded(3, new Color(0.75f, 0.875f, 1f, 0.3f)); EditorGUILayout.HelpBox("If you have not done so already (or you are seeing console warnings), you should assign the new controller asset directly to all Races and Slots that are using this legacy behaviour. Click 'Find and Replace Usage' to do this automatically.", MessageType.Info); //Allows the user to find and replace usage again (if for example they have added races or slots that use the old converters) if (GUILayout.Button("Find and Replace Usage")) { var confrimMsg = "This will replace all usage of " + _target.gameObject.name + " with " + (converterControllerProp.objectReferenceValue as DynamicDNAConverterController).name + " in all RaceDatas and SlotDatas that are using the old DNAConverterBehaviour."; if (EditorUtility.DisplayDialog("Replace all usage of " + _target.gameObject.name + "?", confrimMsg, "Proceed", "Cancel")) { _target.FindAndReplaceUsage(converterControllerProp.objectReferenceValue as DynamicDNAConverterController); } } GUIHelper.EndVerticalPadded(3); }
public void DrawOverallModifiersGUI() { var overallModifiersProp = serializedObject.FindProperty("_overallModifiers"); var overallModsFoldoutRect = EditorGUILayout.GetControlRect(); overallModsFoldoutRect.height = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; var overallModsLabel = EditorGUI.BeginProperty(overallModsFoldoutRect, new GUIContent(overallModifiersProp.displayName), overallModifiersProp); overallModifiersProp.isExpanded = EditorGUI.Foldout(overallModsFoldoutRect, overallModifiersProp.isExpanded, overallModsLabel, true, foldoutTipStyle); if (overallModifiersProp.isExpanded) { GUIHelper.BeginVerticalPadded(3, new Color(0.75f, 0.875f, 1f, 0.3f)); GUILayout.Space(5); EditorGUILayout.PropertyField(overallModifiersProp); GUIHelper.EndVerticalPadded(3); } EditorGUI.EndProperty(); GUILayout.Space(5); }
public bool ShowArray(System.Type CurrentType, string Filter) { bool HasFilter = false; bool NotFound = false; string actFilter = Filter.Trim().ToLower(); if (actFilter.Length > 0) { HasFilter = true; } Dictionary <string, AssetItem> TypeDic = UAI.GetAssetDictionary(CurrentType); if (!TypeCheckboxes.ContainsKey(CurrentType)) { TypeCheckboxes.Add(CurrentType, new List <bool>()); } List <AssetItem> Items = new List <AssetItem>(); Items.AddRange(TypeDic.Values); int NotInBuild = 0; int VisibleItems = 0; foreach (AssetItem ai in Items) { if (ai._SerializedItem == null) { NotInBuild++; } string Displayed = ai.ToString(UMAAssetIndexer.SortOrder); if (HasFilter && (!Displayed.ToLower().Contains(actFilter))) { continue; } VisibleItems++; } if (TypeCheckboxes[CurrentType].Count != VisibleItems) { TypeCheckboxes[CurrentType].Clear(); TypeCheckboxes[CurrentType].AddRange(new bool[VisibleItems]); } NotInBuildCount += NotInBuild; GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); Toggles[CurrentType] = EditorGUILayout.Foldout(Toggles[CurrentType], CurrentType.Name + ": " + VisibleItems + "/" + TypeDic.Count + " Item(s). " + NotInBuild + " Not in build."); GUILayout.EndHorizontal(); if (Toggles[CurrentType]) { Items.Sort(); GUIHelper.BeginVerticalPadded(5, new Color(0.75f, 0.875f, 1f)); GUILayout.BeginHorizontal(); GUILayout.Label("Sorted By: " + UMAAssetIndexer.SortOrder, GUILayout.MaxWidth(160)); foreach (string s in UMAAssetIndexer.SortOrders) { if (GUILayout.Button(s, GUILayout.Width(80))) { UMAAssetIndexer.SortOrder = s; } } GUILayout.EndHorizontal(); int CurrentVisibleItem = 0; foreach (AssetItem ai in Items) { string lblBuild = "B-"; string lblVal = ai.ToString(UMAAssetIndexer.SortOrder); if (HasFilter && (!lblVal.ToLower().Contains(actFilter))) { continue; } if (ai._Name == "< Not Found!>") { NotFound = true; } GUILayout.BeginHorizontal(EditorStyles.textField); TypeCheckboxes[CurrentType][CurrentVisibleItem] = EditorGUILayout.Toggle(TypeCheckboxes[CurrentType][CurrentVisibleItem++], GUILayout.Width(20)); if (ai._SerializedItem == null) { lblVal += "<Not in Build>"; lblBuild = "B+"; } if (GUILayout.Button(lblVal, EditorStyles.label)) { Object o = AssetDatabase.LoadMainAssetAtPath(ai._Path); EditorGUIUtility.PingObject(o); Selection.activeObject = o; } if (GUILayout.Button(lblBuild, GUILayout.Width(35))) { if (ai._SerializedItem == null) { if (!ai.IsAssetBundle) { ai.CachSerializedItem(); } } else { ai.ReleaseItem(); } } if (GUILayout.Button("-", GUILayout.Width(20.0f))) { DeletedDuringGUI.Add(ai); } GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(); if (NotFound) { GUILayout.Label("Warning - Some items not found!"); } else { GUILayout.Label("All Items appear OK"); } GUILayout.EndHorizontal(); if (CurrentType == typeof(SlotDataAsset) || CurrentType == typeof(OverlayDataAsset)) { GUIHelper.BeginVerticalPadded(5, new Color(0.65f, 0.65f, 0.65f)); GUILayout.Label("Utilities"); GUILayout.Space(10); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Select All")) { ProcessItems(CurrentType, null, HasFilter, actFilter, Items, SelectItems); } if (GUILayout.Button("Select None")) { ProcessItems(CurrentType, null, HasFilter, actFilter, Items, DeselectItems); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Remove Checked")) { ProcessItems(CurrentType, TypeCheckboxes[CurrentType], HasFilter, actFilter, Items, RemoveChecked); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); SelectedMaterial = (UMAMaterial)EditorGUILayout.ObjectField(SelectedMaterial, typeof(UMAMaterial), false); GUILayout.Label("Apply to checked: "); if (GUILayout.Button("Unassigned")) { ProcessItems(CurrentType, TypeCheckboxes[CurrentType], HasFilter, actFilter, Items, SetItemNullMaterial); } if (GUILayout.Button("All")) { ProcessItems(CurrentType, TypeCheckboxes[CurrentType], HasFilter, actFilter, Items, SetItemMaterial); } EditorGUILayout.EndHorizontal(); GUIHelper.EndVerticalPadded(5); } GUIHelper.EndVerticalPadded(5); } return(NotFound); }
public bool ShowArray(System.Type CurrentType, string Filter) { bool HasFilter = false; bool NotFound = false; string actFilter = Filter.Trim().ToLower(); if (actFilter.Length > 0) { HasFilter = true; } Dictionary <string, AssetItem> TypeDic = UAI.GetAssetDictionary(CurrentType); List <AssetItem> Items = new List <AssetItem>(); Items.AddRange(TypeDic.Values); int NotInBuild = 0; int VisibleItems = 0; foreach (AssetItem ai in Items) { if (ai._SerializedItem == null) { NotInBuild++; } string Displayed = ai.ToString(UMAAssetIndexer.SortOrder); if (HasFilter && (!Displayed.ToLower().Contains(actFilter))) { continue; } VisibleItems++; } NotInBuildCount += NotInBuild; GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); Toggles[CurrentType] = EditorGUILayout.Foldout(Toggles[CurrentType], CurrentType.Name + ": " + VisibleItems + "/" + TypeDic.Count + " Item(s). " + NotInBuild + " Not in build."); GUILayout.EndHorizontal(); if (Toggles[CurrentType]) { Items.Sort(); GUIHelper.BeginVerticalPadded(5, new Color(0.75f, 0.875f, 1f)); GUILayout.BeginHorizontal(); GUILayout.Label("Sorted By: " + UMAAssetIndexer.SortOrder, GUILayout.MaxWidth(160)); foreach (string s in UMAAssetIndexer.SortOrders) { if (GUILayout.Button(s, GUILayout.Width(80))) { UMAAssetIndexer.SortOrder = s; } } GUILayout.EndHorizontal(); foreach (AssetItem ai in Items) { string lblBuild = "B-"; string lblVal = ai.ToString(UMAAssetIndexer.SortOrder); if (HasFilter && (!lblVal.ToLower().Contains(actFilter))) { continue; } if (ai._Name == "< Not Found!>") { NotFound = true; } GUILayout.BeginHorizontal(EditorStyles.textField); if (ai._SerializedItem == null) { lblVal += "<Not in Build>"; lblBuild = "B+"; } if (GUILayout.Button(lblVal /* ai._Name + " (" + ai._AssetBaseName + ")" */, EditorStyles.label)) { EditorGUIUtility.PingObject(AssetDatabase.LoadMainAssetAtPath(ai._Path)); } if (GUILayout.Button(lblBuild, GUILayout.Width(35))) { if (ai._SerializedItem == null) { // Force the item to load. Object o = ai.Item; } else { ai.ReleaseItem(); } } if (GUILayout.Button("-", GUILayout.Width(20.0f))) { DeletedDuringGUI.Add(ai); } GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(); if (NotFound) { GUILayout.Label("Warning - Some items not found!"); } else { GUILayout.Label("All Items appear OK"); } GUILayout.EndHorizontal(); if (CurrentType == typeof(SlotDataAsset) || CurrentType == typeof(OverlayDataAsset)) { GUIHelper.BeginVerticalPadded(5, new Color(0.65f, 0.65f, 0.65f)); GUILayout.Label("Utilities"); GUILayout.Space(10); EditorGUILayout.BeginHorizontal(); SelectedMaterial = (UMAMaterial)EditorGUILayout.ObjectField(SelectedMaterial, typeof(UMAMaterial), false); GUILayout.Label("Assign To"); if (GUILayout.Button("Unassigned")) { foreach (AssetItem ai in Items) { string lblVal = ai.ToString(UMAAssetIndexer.SortOrder); if (HasFilter && (!lblVal.ToLower().Contains(actFilter))) { continue; } if (ai._Type == typeof(SlotDataAsset)) { if ((ai.Item as SlotDataAsset).material != null) { continue; } (ai.Item as SlotDataAsset).material = SelectedMaterial; } if (ai._Type == typeof(OverlayDataAsset)) { if ((ai.Item as OverlayDataAsset).material != null) { continue; } (ai.Item as OverlayDataAsset).material = SelectedMaterial; } } } if (GUILayout.Button("All")) { foreach (AssetItem ai in Items) { string lblVal = ai.ToString(UMAAssetIndexer.SortOrder); if (HasFilter && (!lblVal.ToLower().Contains(actFilter))) { continue; } if (ai._Type == typeof(SlotDataAsset)) { (ai.Item as SlotDataAsset).material = SelectedMaterial; } if (ai._Type == typeof(OverlayDataAsset)) { (ai.Item as OverlayDataAsset).material = SelectedMaterial; } } } EditorGUILayout.EndHorizontal(); GUIHelper.EndVerticalPadded(5); } GUIHelper.EndVerticalPadded(5); } return(NotFound); }
public override void OnInspectorGUI() { _target = (UMAHackable)target; _target.Init(); bool changed = false; _applyStandardUMABoneFiltersProp = serializedObject.FindProperty("_applyStandardUMABoneFilters"); //Add the standard Hackable fields _target.alternatePrefab = EditorGUILayout.ObjectField(new GUIContent("Alternate prefab", "An alternative prefab to use if the character becomes a ragdoll as a result of hacking!"), (Object)_target.alternatePrefab, typeof(GameObject), false); _target.infillMaterial = (Material)EditorGUILayout.ObjectField(new GUIContent("Infill Material", "A material to use to fill the gaps in a mesh, might be a bloody stump kind of thing"), (Object)_target.infillMaterial, typeof(Material), false); if (_target.infillMaterial != null) { _target.infillMode = (InfillMode)EditorGUILayout.EnumPopup(new GUIContent("Infill Mode", "'Sloppy is more relaiable and less processor intensive, but your 'infill' texture may be distorted. 'Meticulous' will attempt to fill the top of the sliced mesh perfectly but might fail to do so"), _target.infillMode); } //TODO Add 'components to remove on Hack' if necessary //TODO Add 'components to add on Hack' if required EditorGUILayout.Space(); //lets use our indented block for this GUIHelper.BeginVerticalPadded(3, new Color(0.75f, 0.875f, 1f, 0.3f)); EditorGUILayout.HelpBox("Select which bones are severable. Use the 'Standard UMA Filters' button to remove 'Adjust' bones etc:", MessageType.Info); EditorGUI.indentLevel++; _availableTransforms = new List <UMATransform>(_target.umaSeverables); _selectedTransforms = new List <UMATransform>(_target.selectedUmaSeverables); GUILayout.BeginHorizontal(); EditorGUI.BeginChangeCheck(); _applyStandardUMABoneFiltersProp.boolValue = GUILayout.Toggle(_applyStandardUMABoneFiltersProp.boolValue, new GUIContent("Standard UMA Filters", "Filter out standard UMA Bones like 'Global', 'Position' and the 'Adjust' bones from this list"), "Button"); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); _target.UpdateSeverablesFromActiveRecipe((_applyStandardUMABoneFiltersProp.boolValue ? _standardUMABoneFilters : null)); changed = true; } if (GUILayout.Button("Select All")) { for (int i = 0; i < _availableTransforms.Count; i++) { if (!IsUMATransformInList(_availableTransforms[i], _selectedTransforms)) { _selectedTransforms.Add(_availableTransforms[i]); } } changed = true; } if (GUILayout.Button("Deselect All")) { _selectedTransforms.Clear(); changed = true; } GUILayout.EndHorizontal(); //Output the list of avalable bones (filtered) for (int i = 0; i < _availableTransforms.Count; i++) { var wasSelected = IsUMATransformInList(_availableTransforms[i], _selectedTransforms); var isSelected = EditorGUILayout.Toggle(_availableTransforms[i].name, wasSelected); //UMATransform doesn't have a System.IEquatable<UMATransform> so we have to use UMATransformComparer if (isSelected != wasSelected) { if (isSelected) { _selectedTransforms.Add(_availableTransforms[i]); } else if (!isSelected && wasSelected) { for (int si = 0; si < _selectedTransforms.Count; si++) { if (_selectedTransforms[si].hash == _availableTransforms[i].hash) { _selectedTransforms.RemoveAt(si); break; } } } changed = true; } } if (changed) { _target.ClearSelectedSeverables(); for (int i = 0; i < _selectedTransforms.Count; i++) { _target.AddUMATransformToSeverables(_selectedTransforms[i]); } //do we want to try and update the associated transforms here too (i.e. if the user has used bone builder the actual severable transforms could be updated here too) //I think so... _target.ConvertUMASeverablesToSeverables(); serializedObject.Update(); } EditorGUI.indentLevel--; GUIHelper.EndVerticalPadded(3); //base.OnInspectorGUI(); }
public override void OnInspectorGUI() { serializedObject.Update(); SerializedProperty poses = serializedObject.FindProperty("poses"); if (doBoneAdd) { if (addBoneNames != null && addBoneNames.Count > 0) { foreach (string s in addBoneNames) { AddABone(poses, s); } } else if (!string.IsNullOrEmpty(addBoneName)) { AddABone(poses, addBoneName); } activeBoneIndex = BAD_INDEX; editBoneIndex = BAD_INDEX; mirrorBoneIndex = BAD_INDEX; addBoneIndex = 0; addBoneName = ""; addBoneNames.Clear(); doBoneAdd = false; } if (doBoneRemove) { poses.DeleteArrayElementAtIndex(removeBoneIndex - 1); activeBoneIndex = BAD_INDEX; editBoneIndex = BAD_INDEX; mirrorBoneIndex = BAD_INDEX; removeBoneIndex = 0; doBoneRemove = false; } // HACK if (!dynamicDNAConverterMode) { EditorGUILayout.HelpBox("Select a built UMA (DynamicCharacterAvatar, DynamicAvatar, UMAData) to enable editing and addition of new bones.", MessageType.Info); sourceUMA = EditorGUILayout.ObjectField("Source UMA", sourceUMA, typeof(UMAData), true) as UMAData; saveUMAData = sourceUMA; } else { if (sourceUMA != null) { EditorGUILayout.HelpBox("Switch to 'Scene View' and you will see gizmos to help you edit the positions of the pose bones below that you choose to 'Edit'", MessageType.Info); } } if (sourceUMA != null) { if (context == null) { context = new UMABonePoseEditorContext(); } if (context.activeUMA != sourceUMA) { context.activeUMA = sourceUMA; ReloadFullTree(); } } // Weight of pose on preview model if (haveValidContext && !dynamicDNAConverterMode) { EditorGUILayout.BeginHorizontal(); GUILayout.Space(addRemovePadding); EditorGUI.BeginDisabledGroup(haveEditTarget); previewWeight = EditorGUILayout.Slider(previewGUIContent, previewWeight, 0f, 1f); EditorGUI.EndDisabledGroup(); GUILayout.Space(addRemovePadding); EditorGUILayout.EndHorizontal(); } GUILayout.Space(EditorGUIUtility.singleLineHeight / 2f); // Toolbar GUIHelper.BeginVerticalPadded(); MirrorAxis = EditorGUILayout.Popup("Mirror Axis", MirrorAxis, MirrorAxises); GUILayout.BeginHorizontal(); if (GUILayout.Button("Find UMA in scene")) { UMAData data = GameObject.FindObjectOfType <UMAData>(); if (data != null) { sourceUMA = data; saveUMAData = data; var active = Selection.activeObject; Selection.activeGameObject = data.gameObject; SceneView.FrameLastActiveSceneView(); Selection.activeObject = active; } } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Convert all Left/Right")) { for (int i = 0; i < poses.arraySize; i++) { FlipBone(poses, i); } } if (GUILayout.Button("Mirror to opposite")) { // find the opposite bone. // Copy the parms // flip it with FlipBone } GUILayout.EndHorizontal(); highlight = EditorGUILayout.TextField("Highlight bones containing: ", highlight); GUIHelper.EndVerticalPadded(); // string controlName = GUI.GetNameOfFocusedControl(); // if ((controlName != null) && (controlName.Length > 0)) // Debug.Log(controlName); // These can get corrupted by undo, so just rebuild them string[] removeBoneOptions = new string[targetPose.poses.Length + 1]; removeBoneOptions[0] = " "; for (int i = 0; i < targetPose.poses.Length; i++) { removeBoneOptions[i + 1] = targetPose.poses[i].bone; } string[] addBoneOptions = new string[1]; if (haveValidContext) { List <string> addList = new List <string>(context.boneList); addList.Insert(0, " "); for (int i = 0; i < targetPose.poses.Length; i++) { addList.Remove(targetPose.poses[i].bone); } addBoneOptions = addList.ToArray(); } if (editBoneIndex != BAD_INDEX) { SerializedProperty editBone = poses.GetArrayElementAtIndex(editBoneIndex); SerializedProperty bone = editBone.FindPropertyRelative("bone"); string boneName = bone.stringValue; string mirrorBoneName = ""; if (boneName.StartsWith("Left")) { mirrorBoneName = boneName.Replace("Left", "Right"); //mirrorBoneIndex = FindMirrorBone(mirrorName); } if (boneName.StartsWith("Right")) { mirrorBoneName = boneName.Replace("Right", "Left"); //mirrorBoneIndex = FindMirrorBone(mirrorName); } } // List of existing bones poses.isExpanded = EditorGUILayout.Foldout(poses.isExpanded, "Pose Bones (" + poses.arraySize + ")"); if (poses.isExpanded) { for (int i = 0; i < poses.arraySize; i++) { SerializedProperty pose = poses.GetArrayElementAtIndex(i); drawBoneIndex = i; PoseBoneDrawer(pose); } } GUILayout.Space(EditorGUIUtility.singleLineHeight); // Controls for adding a new bone EditorGUILayout.BeginHorizontal(); GUILayout.Space(addRemovePadding); if (haveValidContext) { EditorGUI.BeginDisabledGroup(addBoneIndex < 1); if (GUILayout.Button(addBoneGUIContent, GUILayout.Width(90f))) { addBoneName = addBoneOptions[addBoneIndex]; doBoneAdd = true; } EditorGUI.EndDisabledGroup(); EditorGUILayout.BeginVertical(); GUILayout.Space(buttonVerticalOffset); addBoneIndex = EditorGUILayout.Popup(addBoneIndex, addBoneOptions); EditorGUILayout.EndVertical(); } else { EditorGUI.BeginDisabledGroup(addBoneName.Length < minBoneNameLength); if (GUILayout.Button(addBoneGUIContent, GUILayout.Width(90f))) { doBoneAdd = true; } EditorGUI.EndDisabledGroup(); EditorGUILayout.BeginVertical(); GUILayout.Space(buttonVerticalOffset); addBoneName = EditorGUILayout.TextField(addBoneName); EditorGUILayout.EndVertical(); } GUILayout.Space(addRemovePadding); EditorGUILayout.EndHorizontal(); // Controls for removing existing bone EditorGUILayout.BeginHorizontal(); GUILayout.Space(addRemovePadding); EditorGUI.BeginDisabledGroup(removeBoneIndex < 1); if (GUILayout.Button(removeBoneGUIContent, GUILayout.Width(90f))) { doBoneRemove = true; } EditorGUI.EndDisabledGroup(); EditorGUILayout.BeginVertical(); GUILayout.Space(buttonVerticalOffset); removeBoneIndex = EditorGUILayout.Popup(removeBoneIndex, removeBoneOptions); EditorGUILayout.EndVertical(); GUILayout.Space(addRemovePadding); EditorGUILayout.EndHorizontal(); if (boneTreeView.RootNode != null) { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Expand All")) { boneTreeView.ExpandAll(); } if (GUILayout.Button("Collapse All")) { boneTreeView.CollapseAll(); } if (GUILayout.Button("Select None")) { List <int> noselection = new List <int>(); boneTreeView.SetSelection(noselection); } EditorGUI.BeginDisabledGroup(!boneTreeView.HasSelection()); if (GUILayout.Button("Add Selected")) { addBoneNames = boneTreeView.GetSelectedBones(); doBoneAdd = true; } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); filter = GUILayout.TextField(filter); if (GUILayout.Button("Filter", GUILayout.Width(80))) { ReloadFilteredTree(); } if (GUILayout.Button("Clear", GUILayout.Width(80))) { filter = ""; ReloadFullTree(); } EditorGUILayout.EndHorizontal(); GUILayout.Space(10); string filterstate = "Bone List (No filter)"; if (filtered) { filterstate = "Bone List (filter=\"" + lastFilter + "\")"; } EditorGUILayout.LabelField(filterstate, EditorStyles.toolbarButton); Rect r = GUILayoutUtility.GetLastRect(); scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, true); r.yMin = 0; //r.yMax + 60; r.height = boneTreeView.totalHeight; GUILayout.Space(boneTreeView.totalHeight); boneTreeView.OnGUI(r); GUILayout.EndScrollView(); } serializedObject.ApplyModifiedProperties(); }
public override void OnInspectorGUI() { thisDDCC = target as DynamicDNAConverterCustomizer; serializedObject.Update(); EditorGUILayout.PropertyField(serializedObject.FindProperty("dynamicDnaConverterPrefab")); EditorGUILayout.PropertyField(serializedObject.FindProperty("TposeAnimatorController")); EditorGUILayout.PropertyField(serializedObject.FindProperty("AposeAnimatorController")); EditorGUILayout.PropertyField(serializedObject.FindProperty("MovementAnimatorController")); if (Application.isPlaying) { EditorGUILayout.BeginHorizontal(); if (serializedObject.FindProperty("TposeAnimatorController").objectReferenceValue != null) { if (GUILayout.Button("Set T-Pose")) { thisDDCC.SetTPoseAni(); } } if (serializedObject.FindProperty("AposeAnimatorController").objectReferenceValue != null) { if (GUILayout.Button("Set A-Pose")) { thisDDCC.SetAPoseAni(); } } if (serializedObject.FindProperty("MovementAnimatorController").objectReferenceValue != null) { if (GUILayout.Button("Animate UMA")) { thisDDCC.SetMovementAni(); } } EditorGUILayout.EndHorizontal(); } EditorGUILayout.Space(); EditorGUILayout.PropertyField(serializedObject.FindProperty("targetUMA")); EditorGUILayout.PropertyField(serializedObject.FindProperty("guideUMA")); if (serializedObject.FindProperty("guideUMA").objectReferenceValue != null && Application.isPlaying) { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Align Guide To Target")) { thisDDCC.AlignGuideToTarget(); } if (GUILayout.Button("Import Guide DNA Values")) { thisDDCC.ImportGuideDNAValues(); } EditorGUILayout.EndHorizontal(); } if (Application.isPlaying) { SerializedProperty availableConvertersProp = serializedObject.FindProperty("availableConverters"); SerializedProperty selectedConverterProp = serializedObject.FindProperty("selectedConverter"); List <string> availableConvertersPopup = new List <string>(); availableConvertersPopup.Add("None Selected"); int selectedConverterIndex = 0; int newSelectedConverterIndex = 0; for (int i = 0; i < availableConvertersProp.arraySize; i++) { availableConvertersPopup.Add(availableConvertersProp.GetArrayElementAtIndex(i).objectReferenceValue.name); if (selectedConverterProp.objectReferenceValue != null) { if (availableConvertersProp.GetArrayElementAtIndex(i).objectReferenceValue.name == selectedConverterProp.objectReferenceValue.name) { selectedConverterIndex = i + 1; } } } EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); newSelectedConverterIndex = EditorGUILayout.Popup("Target UMA Converter", selectedConverterIndex, availableConvertersPopup.ToArray()); if (EditorGUI.EndChangeCheck()) { if (newSelectedConverterIndex != selectedConverterIndex) { if (newSelectedConverterIndex == 0) { selectedConverterProp.objectReferenceValue = null; } else { selectedConverterProp.objectReferenceValue = availableConvertersProp.GetArrayElementAtIndex(newSelectedConverterIndex - 1).objectReferenceValue; } serializedObject.ApplyModifiedProperties(); thisDDCC.BackupConverter(); } } } if (serializedObject.FindProperty("selectedConverter").objectReferenceValue != null) { thisDDCC.StartListeningForUndo(); GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); EditorGUILayout.LabelField("Import Settings from another Converter", EditorStyles.boldLabel); var ImportFromConverterR = EditorGUILayout.GetControlRect(false); var ImportFromConverterLabelR = ImportFromConverterR; var ImportFromConverterFieldR = ImportFromConverterR; var ImportFromConverterButR = ImportFromConverterR; ImportFromConverterLabelR.width = 140; ImportFromConverterButR.width = 70; ImportFromConverterFieldR.width = ImportFromConverterFieldR.width - ImportFromConverterLabelR.width - ImportFromConverterButR.width; ImportFromConverterFieldR.x = ImportFromConverterLabelR.xMax; ImportFromConverterButR.x = ImportFromConverterFieldR.xMax + 5; EditorGUI.LabelField(ImportFromConverterLabelR, "Import from Converter"); EditorGUI.ObjectField(ImportFromConverterFieldR, serializedObject.FindProperty("converterToImport"), GUIContent.none); if (serializedObject.FindProperty("converterToImport").objectReferenceValue == null) { EditorGUI.BeginDisabledGroup(true); } if (GUI.Button(ImportFromConverterButR, "Import")) { if (thisDDCC.ImportConverterValues()) { serializedObject.FindProperty("converterToImport").objectReferenceValue = null; } } if (serializedObject.FindProperty("converterToImport").objectReferenceValue == null) { EditorGUI.EndDisabledGroup(); } GUIHelper.EndVerticalPadded(10); // Editor thisSDCB; if (SDCBs.TryGetValue((DynamicDNAConverterBehaviour)serializedObject.FindProperty("selectedConverter").objectReferenceValue, out thisSDCB)) { ((DynamicDNAConverterBehaviourEditor)thisSDCB).initialized = true; } else { thisSDCB = Editor.CreateEditor((DynamicDNAConverterBehaviour)serializedObject.FindProperty("selectedConverter").objectReferenceValue, typeof(DynamicDNAConverterBehaviourEditor)); SDCBs.Add((DynamicDNAConverterBehaviour)serializedObject.FindProperty("selectedConverter").objectReferenceValue, thisSDCB); } ((DynamicDNAConverterBehaviourEditor)thisSDCB).minimalMode = true; ((DynamicDNAConverterBehaviourEditor)thisSDCB).thisDDCC = thisDDCC; ((DynamicDNAConverterBehaviourEditor)thisSDCB).umaData = thisDDCC.targetUMA.umaData; GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); EditorGUILayout.LabelField("Edit Values", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); thisSDCB.OnInspectorGUI(); if (EditorGUI.EndChangeCheck()) { thisDDCC.UpdateUMA(); } GUIHelper.EndVerticalPadded(10); GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); EditorGUILayout.LabelField("Save Values", EditorStyles.boldLabel); Rect thisR = EditorGUILayout.GetControlRect(false); var thisButReset = thisR; var thisButSave = thisR; var thisButSaveNew = thisR; thisButReset.width = thisButSave.width = thisButSaveNew.width = (thisR.width / 3) - 2; thisButSave.x = thisButReset.xMax + 5; thisButSaveNew.x = thisButSave.xMax + 5; if (GUI.Button(thisButReset, new GUIContent("Reset", "Undo your changes to the currently selected converter"))) { thisDDCC.RestoreBackupVersion(serializedObject.FindProperty("selectedConverter").objectReferenceValue.name); } if (GUI.Button(thisButSave, new GUIContent("Save", "Save your changes to the currently selected converter"))) { thisDDCC.SaveChanges(); } if (GUI.Button(thisButSaveNew, new GUIContent("Save as New", "Save your changes to a new converter instance"))) { thisDDCC.SaveChangesAsNew(); } GUIHelper.EndVerticalPadded(10); } else { thisDDCC.StopListeningForUndo(); } serializedObject.ApplyModifiedProperties(); }
public override void OnInspectorGUI() { thisDDCC = target as DynamicDNAConverterCustomizer; serializedObject.Update(); EditorGUILayout.PropertyField(serializedObject.FindProperty("dynamicDnaConverterPrefab")); EditorGUILayout.PropertyField(serializedObject.FindProperty("TposeAnimatorController")); EditorGUILayout.PropertyField(serializedObject.FindProperty("AposeAnimatorController")); EditorGUILayout.PropertyField(serializedObject.FindProperty("MovementAnimatorController")); if (Application.isPlaying) { EditorGUILayout.BeginHorizontal(); if (serializedObject.FindProperty("TposeAnimatorController").objectReferenceValue != null) { if (GUILayout.Button("Set T-Pose")) { thisDDCC.SetTPoseAni(); } } if (serializedObject.FindProperty("AposeAnimatorController").objectReferenceValue != null) { if (GUILayout.Button("Set A-Pose")) { thisDDCC.SetAPoseAni(); } } if (serializedObject.FindProperty("MovementAnimatorController").objectReferenceValue != null) { if (GUILayout.Button("Animate UMA")) { thisDDCC.SetMovementAni(); } } EditorGUILayout.EndHorizontal(); } EditorGUILayout.Space(); EditorGUILayout.PropertyField(serializedObject.FindProperty("targetUMA")); EditorGUILayout.PropertyField(serializedObject.FindProperty("guideUMA")); if (serializedObject.FindProperty("guideUMA").objectReferenceValue != null && Application.isPlaying) { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Align Guide To Target")) { thisDDCC.AlignGuideToTarget(); } if (GUILayout.Button("Import Guide DNA Values")) { thisDDCC.ImportGuideDNAValues(); } EditorGUILayout.EndHorizontal(); } if (Application.isPlaying) { //UMA 2.8+ FixDNAPrefabs - this is a runtime only list of IDNAConverters now //SerializedProperty availableConvertersProp = serializedObject.FindProperty("availableConverters"); //SerializedProperty selectedConverterProp = serializedObject.FindProperty("selectedConverter"); List <string> availableConvertersPopup = new List <string>(); availableConvertersPopup.Add("None Selected"); int selectedConverterIndex = 0; int newSelectedConverterIndex = 0; /*for (int i = 0; i < availableConvertersProp.arraySize; i++) * { * availableConvertersPopup.Add(availableConvertersProp.GetArrayElementAtIndex(i).objectReferenceValue.name); * if (selectedConverterProp.objectReferenceValue != null) * if (availableConvertersProp.GetArrayElementAtIndex(i).objectReferenceValue.name == selectedConverterProp.objectReferenceValue.name) * { * selectedConverterIndex = i + 1; * } * }*/ for (int i = 0; i < thisDDCC.availableConverters.Count; i++) { if (!(thisDDCC.availableConverters[i] is IDynamicDNAConverter) || thisDDCC.availableConverters[i] == null) { continue; } availableConvertersPopup.Add(thisDDCC.availableConverters[i].name); if (thisDDCC.selectedConverter != null && thisDDCC.selectedConverter == thisDDCC.availableConverters[i]) { selectedConverterIndex = i + 1; } } EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); newSelectedConverterIndex = EditorGUILayout.Popup("Target UMA Converter", selectedConverterIndex, availableConvertersPopup.ToArray()); if (EditorGUI.EndChangeCheck()) { if (newSelectedConverterIndex != selectedConverterIndex) { if (newSelectedConverterIndex == 0) { thisDDCC.selectedConverter = null; } else { thisDDCC.selectedConverter = thisDDCC.availableConverters[newSelectedConverterIndex - 1]; } serializedObject.ApplyModifiedProperties();//Doesn't make sense now? thisDDCC.BackupConverter(); } } } if (thisDDCC.selectedConverter != null) { thisDDCC.StartListeningForUndo(); //import like this makes no sense now /* * GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f, 0.3f)); * EditorGUILayout.LabelField("Import Settings from another Converter", EditorStyles.boldLabel); * var ImportFromConverterR = EditorGUILayout.GetControlRect(false); * var ImportFromConverterLabelR = ImportFromConverterR; * var ImportFromConverterFieldR = ImportFromConverterR; * var ImportFromConverterButR = ImportFromConverterR; * ImportFromConverterLabelR.width = 140; * ImportFromConverterButR.width = 70; * ImportFromConverterFieldR.width = ImportFromConverterFieldR.width - ImportFromConverterLabelR.width - ImportFromConverterButR.width; * ImportFromConverterFieldR.x = ImportFromConverterLabelR.xMax; * ImportFromConverterButR.x = ImportFromConverterFieldR.xMax + 5; * EditorGUI.LabelField(ImportFromConverterLabelR, "Import from Converter"); * EditorGUI.ObjectField(ImportFromConverterFieldR, serializedObject.FindProperty("converterToImport"), GUIContent.none); * if (serializedObject.FindProperty("converterToImport").objectReferenceValue == null) * EditorGUI.BeginDisabledGroup(true); * if(GUI.Button(ImportFromConverterButR, "Import")) * { * if (thisDDCC.ImportConverterValues()) * { * serializedObject.FindProperty("converterToImport").objectReferenceValue = null; * } * } * if (serializedObject.FindProperty("converterToImport").objectReferenceValue == null) * EditorGUI.EndDisabledGroup(); * GUIHelper.EndVerticalPadded(10); */ // Editor thisSDCB; if (SDCBs.TryGetValue(thisDDCC.selectedConverter, out thisSDCB)) { if (thisDDCC.selectedConverter is DynamicDNAConverterBehaviour) { ((DynamicDNAConverterBehaviourEditor)thisSDCB).initialized = true; } else if (thisDDCC.selectedConverter is DynamicDNAConverterController) { //Might need UMAData to work //((DynamicDNAConverterControllerInspector)thisSDCB) } } else { if (thisDDCC.selectedConverter is DynamicDNAConverterBehaviour) { thisSDCB = Editor.CreateEditor((thisDDCC.selectedConverter as DynamicDNAConverterBehaviour), typeof(DynamicDNAConverterBehaviourEditor)); SDCBs.Add(thisDDCC.selectedConverter, thisSDCB); } else if (thisDDCC.selectedConverter is DynamicDNAConverterController) { thisSDCB = Editor.CreateEditor((thisDDCC.selectedConverter as DynamicDNAConverterController), typeof(DynamicDNAConverterControllerInspector)); SDCBs.Add(thisDDCC.selectedConverter, thisSDCB); } } if (thisDDCC.selectedConverter is DynamicDNAConverterBehaviour) { ((DynamicDNAConverterBehaviourEditor)thisSDCB).thisDDCC = thisDDCC; ((DynamicDNAConverterBehaviourEditor)thisSDCB).umaData = thisDDCC.targetUMA.umaData; } else if (thisDDCC.selectedConverter is DynamicDNAConverterController) { } GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f, 0.3f)); EditorGUILayout.LabelField("Edit Values", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); thisSDCB.OnInspectorGUI(); if (EditorGUI.EndChangeCheck()) { thisDDCC.UpdateUMA(); } GUIHelper.EndVerticalPadded(10); //The following only makes sense for DynamicDNAConverterBehaviour right now //But we want to make them both work the same, and work the default Unity way //i.e. now we want to keep the changes by default and revert them if the user requests that //Altho changes to a component DONT get changed permanently in Play mode //and embedding the editor makes it LOOK LIKE we are editing a component if (thisDDCC.selectedConverter is DynamicDNAConverterBehaviour) { GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f, 0.3f)); EditorGUILayout.LabelField("Save Values", EditorStyles.boldLabel); Rect thisR = EditorGUILayout.GetControlRect(false); var thisButReset = thisR; var thisButSave = thisR; var thisButSaveNew = thisR; thisButReset.width = thisButSave.width = thisButSaveNew.width = (thisR.width / 3) - 2; thisButSave.x = thisButReset.xMax + 5; thisButSaveNew.x = thisButSave.xMax + 5; if (GUI.Button(thisButReset, new GUIContent("Reset", "Undo your changes to the currently selected converter"))) { thisDDCC.RestoreBackupVersion(serializedObject.FindProperty("selectedConverter").objectReferenceValue.name); } if (GUI.Button(thisButSave, new GUIContent("Save", "Save your changes to the currently selected converter"))) { thisDDCC.SaveChanges(); } if (GUI.Button(thisButSaveNew, new GUIContent("Save as New", "Save your changes to a new converter instance"))) { thisDDCC.SaveChangesAsNew(); } GUIHelper.EndVerticalPadded(10); } DrawBonePoseCreationTools(); } else { thisDDCC.StopListeningForUndo(); } serializedObject.ApplyModifiedProperties(); }
/// <summary> /// Performs editing on a UMAMaterialPropertyBlock. Returns true if changed, false if not changed /// </summary> /// <param name="umpb">UMAMaterialPropertyBlock</param> /// <returns></returns> public static bool OnGUI(UMAMaterialPropertyBlock umpb) { UMAMaterialPropertyBlock.CheckInitialize(); GUILayout.Space(5); bool changed = false; EditorGUI.BeginChangeCheck(); GUIHelper.BeginVerticalPadded(5, new Color(0.65f, 0.675f, 1f)); GUILayout.Label("Shader Properties"); GUILayout.BeginHorizontal(); TypeIndex = EditorGUILayout.Popup(TypeIndex, UMAMaterialPropertyBlock.PropertyTypeStrings); if (GUILayout.Button("Add Type")) { umpb.AddProperty(UMAMaterialPropertyBlock.availableTypes[TypeIndex], UMAMaterialPropertyBlock.PropertyTypeStrings[TypeIndex]); } GUILayout.EndHorizontal(); bool dark = false; UMAProperty delme = null; if (umpb.shaderProperties != null) { foreach (UMAProperty up in umpb.shaderProperties) { if (up == null) { continue; } GUIHelper.BeginVerticalIndented(3, new Color(0.75f, 0.75f, 1f)); if (dark) { GUIHelper.BeginVerticalPadded(5, new Color(0.85f, 0.85f, 1f)); dark = false; } else { GUIHelper.BeginVerticalPadded(5, new Color(0.65f, 0.65f, 0.9f)); dark = true; } if (up.OnGUI()) { delme = up; } GUIHelper.EndVerticalPadded(5); GUIHelper.EndVerticalIndented(); } if (delme != null) { umpb.shaderProperties.Remove(delme); } } GUIHelper.EndVerticalPadded(5); GUILayout.Space(5); changed = EditorGUI.EndChangeCheck(); return(changed); }
public void DrawLegacyStartingPoseGUI() { GUIHelper.BeginVerticalPadded(3, new Color(0.75f, 0.875f, 1f, 0.3f)); EditorGUI.indentLevel++; startingPoseExpanded = EditorGUILayout.Foldout(startingPoseExpanded, "Starting Pose"); if (startingPoseExpanded) { GUIHelper.BeginVerticalPadded(3, new Color(0.75f, 0.875f, 1f, 0.3f)); EditorGUI.indentLevel++; startingPoseInfoExpanded = EditorGUILayout.Foldout(startingPoseInfoExpanded, "INFO"); if (startingPoseInfoExpanded) { EditorGUILayout.HelpBox("The 'Starting Pose' is the initial position/rotation/scale of all the bones in this Avatar's skeleton. Use this to completely transform the mesh of your character. You could (for example) transform standard UMA characters into a backwards compatible 'Short Squat Dwarf' or a 'Bobble- headded Toon'. Optionally, you can create an UMABonePose asset from an FBX model using the UMA > Pose Tools > Bone Pose Builder and add the resulting asset here. After you have added or created a UMABonePose asset, you can add and edit the position, rotation and scale settings for any bone in the active character's skeleton in the 'Bone Poses' section.'.", MessageType.Info); } EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(serializedObject.FindProperty("_startingPose"), new GUIContent("Starting UMABonePose", "Define an asset that will set the starting bone poses of any Avatar using this converter")); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); //If this gets set we need to back it up if (thisDDCC != null) { thisDDCC.BackupConverter(); } } //Draw the poses array from the Asset if set or show controls to create a new asset. SerializedProperty bonePoseAsset = serializedObject.FindProperty("_startingPose"); //If the asset isn't null and we are in playmode set the context.activeUMA to this umaData for live editing if (bonePoseAsset.objectReferenceValue != null && minimalMode) { //if there is an UMABonePose popup inspector open set the umaData as its sourceUMA if (UMA.PoseTools.UMABonePoseEditor.livePopupEditor != null) { UMA.PoseTools.UMABonePoseEditor.livePopupEditor.sourceUMA = umaData; UMA.PoseTools.UMABonePoseEditor.livePopupEditor.dynamicDNAConverterMode = true; } } if (bonePoseAsset.objectReferenceValue != null) { EditorGUILayout.PropertyField(serializedObject.FindProperty("startingPoseWeight")); } else { if (thisDDCC != null) { var createPoseAssetR = EditorGUILayout.GetControlRect(false); var createPoseAssetRLabel = createPoseAssetR; var createPoseAssetRField = createPoseAssetR; var createPoseAssetRButton = createPoseAssetR; createPoseAssetRLabel.width = createPoseAssetRLabel.width / 3 + 7; createPoseAssetRButton.width = 70f; createPoseAssetRField.width = ((createPoseAssetRField.width / 3) * 2) - 82; createPoseAssetRField.x = createPoseAssetRLabel.xMax; createPoseAssetRButton.x = createPoseAssetRField.xMax + 5; EditorGUI.LabelField(createPoseAssetRLabel, new GUIContent("New BonePose Asset", "Create a new empty UMABonePose with the name of your choosing.")); createBonePoseAssetName = EditorGUI.TextField(createPoseAssetRField, createBonePoseAssetName); if (GUI.Button(createPoseAssetRButton, "Create It")) //need to do the button enabled thing here { var newDnaAsset = thisDDCC.CreatePoseAsset("", createBonePoseAssetName); if (newDnaAsset != null) { //set this asset as the used asset bonePoseAsset.objectReferenceValue = newDnaAsset; serializedObject.ApplyModifiedProperties(); createBonePoseAssetName = ""; } } } else { EditorGUILayout.HelpBox("Edit a character that uses this converter in the 'DynamicDna Converter Behaviour Customizer' scene and you can create a StartingPoseAsset automatically here", MessageType.Info); } } EditorGUI.indentLevel--; GUIHelper.EndVerticalPadded(3); } EditorGUI.indentLevel--; GUIHelper.EndVerticalPadded(3); serializedObject.ApplyModifiedProperties(); }
#pragma warning restore 618 private void DrawLegacySkeletonModifiersList(SerializedProperty skeletonModifiers) { //THE ACTUAL MODIFIER LIST EditorGUI.indentLevel++; GUIHelper.BeginVerticalPadded(3, new Color(0.75f, 0.875f, 1f, 0.3f)); EditorGUILayout.LabelField("Skeleton Modifiers (" + skeletonModifiers.arraySize + ")", EditorStyles.helpBox); //Search Filters Controls- dont show if we dont have any modifiers if (skeletonModifiers.arraySize > 0) { Rect searchR = EditorGUILayout.GetControlRect(); var searchL = searchR; var searchF = searchR; var searchTL = searchR; var searchTF = searchR; searchL.width = 130; searchF.width = (searchR.width / 3) * 2 - searchL.width; searchF.x = searchR.x + searchL.width; searchTL.width = 35; searchTL.x = searchF.xMax; searchTF.width = (searchR.width / 3) - searchTL.width + (EditorGUI.indentLevel * 15); searchTF.x = searchTL.xMax - (EditorGUI.indentLevel * 15); EditorGUI.LabelField(searchL, "Search Modifiers"); EditorGUI.indentLevel--; skeletonModifiersFilter = EditorGUI.TextField(searchF, skeletonModifiersFilter); EditorGUI.LabelField(searchTL, "By"); skeletonModifiersFilterType = EditorGUI.Popup(searchTF, skeletonModifiersFilterType, skeletonModifiersFilterTypeList); EditorGUI.indentLevel++; } EditorGUI.indentLevel++; for (int i = 0; i < skeletonModifiers.arraySize; i++) { var thisSkelEl = skeletonModifiers.GetArrayElementAtIndex(i); //Search Filters Method if (skeletonModifiersFilterTypeList[skeletonModifiersFilterType] != "DNA") { if (skeletonModifiersFilterType == 1 || skeletonModifiersFilterType == 2 || skeletonModifiersFilterType == 3) { string thisProperty = thisSkelEl.FindPropertyRelative("_property").enumNames[thisSkelEl.FindPropertyRelative("_property").enumValueIndex]; if (skeletonModifiersFilterType == 1) //Position Modifiers { if (thisProperty.IndexOf("position", StringComparison.CurrentCultureIgnoreCase) == -1) { continue; } } else if (skeletonModifiersFilterType == 2) //Rotation Modifiers { if (thisProperty.IndexOf("rotation", StringComparison.CurrentCultureIgnoreCase) == -1) { continue; } } else if (skeletonModifiersFilterType == 3) //scale Modifiers { if (thisProperty.IndexOf("scale", StringComparison.CurrentCultureIgnoreCase) == -1) { continue; } } } else if (skeletonModifiersFilterType == 5) //Adjust Bones { if (thisSkelEl.displayName.IndexOf("adjust", StringComparison.CurrentCultureIgnoreCase) == -1) { continue; } } else if (skeletonModifiersFilterType == 6) //Non Adjust Bones { if (thisSkelEl.displayName.IndexOf("adjust", StringComparison.CurrentCultureIgnoreCase) > -1) { continue; } } } if (skeletonModifiersFilter.Length >= 3) { if (skeletonModifiersFilterTypeList[skeletonModifiersFilterType] != "DNA") { if (thisSkelEl.displayName.IndexOf(skeletonModifiersFilter, StringComparison.CurrentCultureIgnoreCase) == -1) { continue; } } else //Searches for Modifiers that use a given DNA Value- slow but super handy { string[] XYZ = new string[] { "X", "Y", "Z" }; SerializedProperty mods; SerializedProperty thisMod; int modsi; bool _continue = true; foreach (string xyz in XYZ) { mods = thisSkelEl.FindPropertyRelative("_values" + xyz).FindPropertyRelative("_val").FindPropertyRelative("_modifiers"); for (int mi = 0; mi < mods.arraySize; mi++) { thisMod = mods.GetArrayElementAtIndex(mi); modsi = thisMod.FindPropertyRelative("_modifier").enumValueIndex; if (modsi > 3) { if (thisMod.FindPropertyRelative("_DNATypeName").stringValue.IndexOf(skeletonModifiersFilter, StringComparison.CurrentCultureIgnoreCase) > -1) { _continue = false; } } } } if (_continue) { continue; } } } Rect currentRect = EditorGUILayout.GetControlRect(false, _skelModPropDrawer.GetPropertyHeight(thisSkelEl, GUIContent.none)); //Delete button Rect sDelButR = currentRect; sDelButR.x = sDelButR.x + sDelButR.width - 100f; sDelButR.width = 100f; sDelButR.height = EditorGUIUtility.singleLineHeight; if (GUI.Button(sDelButR, "Delete")) { skeletonModifiers.DeleteArrayElementAtIndex(i); continue; } Rect thisSkelRect = new Rect(currentRect.xMin, currentRect.yMin, currentRect.width, _skelModPropDrawer.GetPropertyHeight(thisSkelEl, GUIContent.none)); _skelModPropDrawer.OnGUI(thisSkelRect, thisSkelEl, new GUIContent(thisSkelEl.displayName)); } GUIHelper.EndVerticalPadded(3); EditorGUI.indentLevel--; }
public override void OnInspectorGUI() { if (!initialized) { Init(); } serializedObject.Update(); /* * EditorGUI.BeginDisabledGroup(true); * EditorGUILayout.PropertyField(serializedObject.FindProperty("lastKnownAssetPath")); * EditorGUILayout.PropertyField(serializedObject.FindProperty("lastKnownDuplicateAssetPath")); * EditorGUILayout.PropertyField(serializedObject.FindProperty("lastKnownInstanceID")); * EditorGUI.EndDisabledGroup();*/ SerializedProperty dnaTypeHash = serializedObject.FindProperty("dnaTypeHash"); Rect hashEditorRect = GUILayoutUtility.GetRect(0.0f, EditorGUIUtility.singleLineHeight, GUILayout.ExpandWidth(true)); var hashLabelRect = hashEditorRect; hashLabelRect.xMax = hashEditorRect.xMax / 3; var hashBtnRect = hashEditorRect; hashBtnRect.xMin = hashLabelRect.xMax + (EditorGUI.indentLevel * 20); hashBtnRect.xMax = hashBtnRect.xMin + 50 + (EditorGUI.indentLevel * 20); var hashFieldRect = hashEditorRect; hashFieldRect.xMin = hashBtnRect.xMax - ((EditorGUI.indentLevel * 20) - 10); if (editTypeHashEnabled) { //EditorGUILayout.BeginHorizontal(); EditorGUI.LabelField(hashLabelRect, new GUIContent(dnaTypeHash.displayName, dnaTypeHash.tooltip)); if (GUI.Button(hashBtnRect, "Save")) { editTypeHashEnabled = false; } var originalDnaTypeHash = dnaTypeHash; EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(hashFieldRect, dnaTypeHash, new GUIContent("")); if (EditorGUI.EndChangeCheck()) { //we MUST NOT let this have the same TypeHash as UMADnaHumanoid or UMADnaTutorial, so if people randomly choose that value- dont assign it if (dnaTypeHash.intValue == UMAUtils.StringToHash("UMADnaHumanoid") || dnaTypeHash.intValue == UMAUtils.StringToHash("UMADnaTutorial")) { Debug.LogWarning("You are trying to set a DynamicDNA to the same hash as a UMADnaHumanoid or UMADnaTutorial dna- this is not allowed"); dnaTypeHash = originalDnaTypeHash; } else { serializedObject.ApplyModifiedProperties(); } } //EditorGUILayout.EndHorizontal(); } else { //EditorGUILayout.BeginHorizontal(); EditorGUI.LabelField(hashLabelRect, new GUIContent(dnaTypeHash.displayName, dnaTypeHash.tooltip)); if (GUI.Button(hashBtnRect, "Edit")) { if (EditorUtility.DisplayDialog("Really Change the Hash?", "If you change the DNA Assets hash, any recipes that use this DNA will need to be inspected so they update to the new value. Are you sure?", "Yes", "Cancel")) { editTypeHashEnabled = true; } } EditorGUI.BeginDisabledGroup(true); EditorGUI.PropertyField(hashFieldRect, dnaTypeHash, new GUIContent("")); EditorGUI.EndDisabledGroup(); //EditorGUILayout.EndHorizontal(); } EditorGUILayout.Space(); SerializedProperty Names = serializedObject.FindProperty("Names"); if (Names.arraySize == 0) { EditorGUILayout.HelpBox("Define your the names for you dna by adding them below", MessageType.Info); } //OTHER OPTIONS FOR ADDING/DELETING NAMES - show in a foldout EditorGUI.indentLevel++; otherAddOptionsOpen = EditorGUILayout.Foldout(otherAddOptionsOpen, "Add/Delete Names Options"); EditorGUI.indentLevel--; // if (otherAddOptionsOpen) { //drop area for importing names from other dna assets var dropArea = GUILayoutUtility.GetRect(0.0f, 60.0f, GUILayout.ExpandWidth(true)); dropArea.xMin = dropArea.xMin + (EditorGUI.indentLevel * 15); GUI.Box(dropArea, "Drag DynamicUMADNAAssets here to import their names. Click to pick."); var AddMethods = new GUIContent[dnaNamesAddOpts.Count]; for (int i = 0; i < dnaNamesAddOpts.Count; i++) { AddMethods[i] = new GUIContent(dnaNamesAddOpts[i]); } Rect selectedAddMethodRect = dropArea; selectedAddMethodRect.yMin = dropArea.yMax - EditorGUIUtility.singleLineHeight - 5; selectedAddMethodRect.xMin = dropArea.xMin - ((EditorGUI.indentLevel * 10) - 10); selectedAddMethodRect.xMax = dropArea.xMax - ((EditorGUI.indentLevel * 10) + 10); selectedAddMethod = EditorGUI.Popup(selectedAddMethodRect, new GUIContent("On Import", "Choose whether to 'Add' the names to the current list, or 'Replace' the names with the new list"), selectedAddMethod, AddMethods); var namesList = new List <string>(Names.arraySize); for (int i = 0; i < Names.arraySize; i++) { namesList.Add(Names.GetArrayElementAtIndex(i).stringValue); } ImportDNADropArea(dropArea, namesList, selectedAddMethod); EditorGUILayout.Space(); //Clear all and Add Defaults Buttons Rect clearAndDefaultsRect = GUILayoutUtility.GetRect(0.0f, EditorGUIUtility.singleLineHeight, GUILayout.ExpandWidth(true)); clearAndDefaultsRect.xMin = clearAndDefaultsRect.xMin + (EditorGUI.indentLevel * 15); var defaultsButRect = clearAndDefaultsRect; var clearButRect = clearAndDefaultsRect; defaultsButRect.width = clearAndDefaultsRect.width / 2; clearButRect.xMin = defaultsButRect.xMax; clearButRect.width = clearAndDefaultsRect.width / 2; if (GUI.Button(defaultsButRect, new GUIContent("Add Default Names", "Adds the default names as used by UMA Human Male DNA"))) { AddDefaultNames(); } EditorGUI.BeginDisabledGroup(Names.arraySize == 0); if (GUI.Button(clearButRect, new GUIContent("Clear All Names", "Clears the current names. Cannot be undone."))) { if (EditorUtility.DisplayDialog("Really Clear All Names?", "This will delete all the names in the list and cannot be undone. Are you sure?", "Yes", "Cancel")) { (target as DynamicUMADnaAsset).Names = new string[0]; } } EditorGUI.EndDisabledGroup(); EditorGUILayout.Space(); } //ADD NEW NAME BUTTON EditorGUILayout.BeginHorizontal(); bool canAdd = true; EditorGUI.BeginChangeCheck(); newDNAName = EditorGUILayout.TextField(newDNAName); //this wont bloody clear after the name is added if (EditorGUI.EndChangeCheck()) { //checking the text field seems to only work if its done OUTSIDE this change check ?!?! } //check the name is unique if (newDNAName != "") { for (int ni = 0; ni < Names.arraySize; ni++) { if (Names.GetArrayElementAtIndex(ni).stringValue == newDNAName) { canAdd = false; } } } if (GUILayout.Button("Add DNA Name")) { if (newDNAName == "") { return; } if (canAdd) { //var numNames = Names.arraySize; Names.InsertArrayElementAtIndex(0); Names.GetArrayElementAtIndex(0).stringValue = newDNAName; Names.serializedObject.ApplyModifiedProperties(); newDNAName = ""; EditorGUIUtility.keyboardControl = 0; } } EditorGUILayout.EndHorizontal(); //message that the name exists if (canAdd == false) { EditorGUILayout.HelpBox("That name is already in use.", MessageType.Warning); } //ACTUAL NAMES LIST GUIHelper.BeginVerticalPadded(3, new Color(0.75f, 0.875f, 1f, 0.3f)); EditorGUILayout.LabelField("DNA Names List (" + Names.arraySize + ")", EditorStyles.helpBox); if (Names.arraySize > 0) { for (int i = 0; i < Names.arraySize; i++) { var origName = Names.GetArrayElementAtIndex(i).stringValue; var newName = origName; Rect propRect = EditorGUILayout.GetControlRect(false); Rect fieldRect = propRect; Rect delRect = propRect; fieldRect.width = fieldRect.width - 80f; delRect.x = delRect.x + fieldRect.width + 5f; delRect.width = 75f; EditorGUILayout.BeginHorizontal(); EditorGUI.BeginChangeCheck(); newName = EditorGUI.TextField(fieldRect, "", newName); if (EditorGUI.EndChangeCheck()) { if (newName != origName && newName != "") { Names.GetArrayElementAtIndex(i).stringValue = newName; serializedObject.ApplyModifiedProperties(); } } if (GUI.Button(delRect, "Delete")) { Names.DeleteArrayElementAtIndex(i); continue; } EditorGUILayout.EndHorizontal(); } EditorGUILayout.Space(); Names.serializedObject.ApplyModifiedProperties(); } GUIHelper.EndVerticalPadded(3); }
public override void OnInspectorGUI() { if (!initialized) { Init(); } serializedObject.Update(); GUILayout.Space(5); var dnaHeaderRect = EditorGUILayout.GetControlRect(); GUIHelper.ToolbarStyleHeader(dnaHeaderRect, new GUIContent("DYNAMIC DNA"), _help, ref _helpIsExpanded); var importBtnRect = new Rect(dnaHeaderRect.xMax - 40f, dnaHeaderRect.yMin + 2f, 20f, EditorGUIUtility.singleLineHeight); _importToolsExpanded = GUI.Toggle(importBtnRect, _importToolsExpanded, importContent, _importStyle); GUIHelper.BeginVerticalPadded(3, new Color(0.75f, 0.875f, 1f, 0.3f)); SerializedProperty Names = serializedObject.FindProperty("Names"); if (_importToolsExpanded) { DrawImportNamesTools(); } SerializedProperty dnaTypeHash = serializedObject.FindProperty("dnaTypeHash"); Rect hashEditorRect = GUILayoutUtility.GetRect(0.0f, EditorGUIUtility.singleLineHeight, GUILayout.ExpandWidth(true)); var hashLabelRect = hashEditorRect; hashLabelRect.xMax = hashEditorRect.xMax / 3; var hashBtnRect = hashEditorRect; hashBtnRect.xMin = hashLabelRect.xMax + (EditorGUI.indentLevel * 20); hashBtnRect.xMax = hashBtnRect.xMin + 50 + (EditorGUI.indentLevel * 20); var hashFieldRect = hashEditorRect; hashFieldRect.xMin = hashBtnRect.xMax - ((EditorGUI.indentLevel * 20) - 10); if (editTypeHashEnabled) { EditorGUI.LabelField(hashLabelRect, new GUIContent(dnaTypeHash.displayName, _dnaTypehashTooltip)); if (GUI.Button(hashBtnRect, new GUIContent("Save", _dnaTypehashTooltip))) { editTypeHashEnabled = false; } var originalDnaTypeHash = dnaTypeHash; EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(hashFieldRect, dnaTypeHash, new GUIContent("")); if (EditorGUI.EndChangeCheck()) { //we MUST NOT let this have the same TypeHash as UMADnaHumanoid or UMADnaTutorial, so if people randomly choose that value- dont assign it if (dnaTypeHash.intValue == UMAUtils.StringToHash("UMADnaHumanoid") || dnaTypeHash.intValue == UMAUtils.StringToHash("UMADnaTutorial")) { Debug.LogWarning("You are trying to set a DynamicDNA to the same hash as a UMADnaHumanoid or UMADnaTutorial dna- this is not allowed"); dnaTypeHash = originalDnaTypeHash; } else { serializedObject.ApplyModifiedProperties(); } } } else { EditorGUI.LabelField(hashLabelRect, new GUIContent(dnaTypeHash.displayName, _dnaTypehashTooltip)); if (GUI.Button(hashBtnRect, new GUIContent("Edit", _dnaTypehashTooltip))) { if (EditorUtility.DisplayDialog("Really Change the Hash?", "If you change the DNA Assets hash, any recipes that use this DNA will need to be inspected so they update to the new value. Are you sure?", "Yes", "Cancel")) { editTypeHashEnabled = true; } } EditorGUI.BeginDisabledGroup(true); EditorGUI.PropertyField(hashFieldRect, dnaTypeHash, new GUIContent("")); EditorGUI.EndDisabledGroup(); } EditorGUILayout.Space(); if (Names.arraySize == 0) { EditorGUILayout.HelpBox("Define your the names for your dna by adding them below", MessageType.Info); } //ACTUAL NAMES LIST _dnaNameList.DoLayoutList(); //ADD NEW NAME BUTTON //Moved Add controls into the Reorderable list footer for consistancy //message that the name exists if (!string.IsNullOrEmpty(newDNAName) && canAddNewDNAName == false) { EditorGUILayout.HelpBox("That name is already in use.", MessageType.Warning); } //Clear out indices that have been added to the remove list. for (int i = _dnaNameList.serializedProperty.arraySize - 1; i >= 0; i--) { if (_removeList.Contains(i)) { _dnaNameList.serializedProperty.DeleteArrayElementAtIndex(i); } } _removeList.Clear(); serializedObject.ApplyModifiedProperties(); GUIHelper.EndVerticalPadded(3); GUILayout.Space(5); }