public bool OnGUI() { bool delete; GUIHelper.FoldoutBar(ref _foldout, _overlayData.asset.overlayName, out move, out delete); if (!_foldout) { return(false); } Delete = delete; GUIHelper.BeginHorizontalPadded(10, Color.white); GUILayout.BeginVertical(); bool changed = OnColorGUI(); GUILayout.BeginHorizontal(); foreach (var texture in _textures) { changed |= texture.OnGUI(); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUIHelper.EndVerticalPadded(10); return(changed); }
//draws the coverImages foldout protected virtual bool DrawCoverImagesUI(Type TargetType) { bool doUpdate = false; //FieldInfos var CoverImagesField = TargetType.GetField("coverImages", BindingFlags.Public | BindingFlags.Instance); //field values List <Sprite> coverImages = (List <Sprite>)CoverImagesField.GetValue(target); //drawUI GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); coverImagesIsExpanded = EditorGUILayout.Foldout(coverImagesIsExpanded, new GUIContent("Cover Images")); GUILayout.EndHorizontal(); if (coverImagesIsExpanded) { List <Sprite> prevCoverImages = coverImages; GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); EditorGUILayout.BeginHorizontal(); for (int i = 0; i < coverImages.Count; i++) { EditorGUI.BeginChangeCheck(); var thisImg = EditorGUILayout.ObjectField(coverImages[i], typeof(Sprite), false, GUILayout.Width(75), GUILayout.Height(75)); if (EditorGUI.EndChangeCheck()) { if (thisImg != coverImages[i]) { if (thisImg == null) { coverImages.RemoveAt(i); } else { coverImages[i] = (Sprite)thisImg; } doUpdate = true; } } } EditorGUILayout.EndHorizontal(); if (GUILayout.Button("Add")) { coverImages.Add(new Sprite()); } if (!AreListsEqual <Sprite>(prevCoverImages, coverImages)) { CoverImagesField.SetValue(target, coverImages); } GUIHelper.EndVerticalPadded(10); } GUILayout.Space(-5f); return(doUpdate); }
public override bool OnGUI(string targetName, ref bool _dnaDirty, ref bool _textureDirty, ref bool _meshDirty) { var context = UMAContext.FindInstance(); if (context == null) { var _errorMessage = "Editing a recipe requires a loaded scene with a valid UMAContext."; Debug.LogWarning(_errorMessage); return(false); } bool changed = forceGUIUpdate; //Make a foldout for WardrobeSets - the UI for an individual WardrobeSet is added for each compatible race in the collection GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); bool wsfoldoutOpen = OpenSlots["wardrobeSets"]; wsfoldoutOpen = EditorGUILayout.Foldout(OpenSlots["wardrobeSets"], "Wardrobe Sets"); OpenSlots["wardrobeSets"] = wsfoldoutOpen; GUILayout.EndHorizontal(); if (wsfoldoutOpen) { GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); EditorGUILayout.HelpBox("Wardrobe Sets are added for each 'Compatible Race' assigned above. They can be assigned to an avatar of that race in its 'FullOutfit' slot. 'SharedColors' in this section will be applied to the Avatar when the 'FullOutfit' recipe is applied to the character", MessageType.Info); if (_compatibleRaces.Count > 0) { //dont show shared colors unless there are 'FullOutfits' to apply them to if (_sharedColorsEditor.OnGUI(_recipe)) { changed = true; _textureDirty = true; } for (int i = 0; i < _compatibleRaces.Count; i++) { var thisRace = context.raceLibrary.GetRace(_compatibleRaces[i]); if (thisRace != null) { GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); bool foldoutOpen = OpenSlots[_compatibleRaces[i]]; foldoutOpen = EditorGUILayout.Foldout(OpenSlots[_compatibleRaces[i]], " Wardrobe Set: " + _compatibleRaces[i]); OpenSlots[_compatibleRaces[i]] = foldoutOpen; GUILayout.EndHorizontal(); if (foldoutOpen) { var thisSetEditor = new WardrobeSetEditor(thisRace, _wardrobeCollection[thisRace.raceName], _recipe, false); if (thisSetEditor.OnGUI()) { _wardrobeCollection[thisRace.raceName] = thisSetEditor.WardrobeSet; changed = true; } } } else { //Do the foldout thing but show as 'missing' GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); bool foldoutOpen = OpenSlots[_compatibleRaces[i]]; foldoutOpen = EditorGUILayout.Foldout(OpenSlots[_compatibleRaces[i]], _compatibleRaces[i] + " Wardrobe Set (Missing)"); OpenSlots[_compatibleRaces[i]] = foldoutOpen; GUILayout.EndHorizontal(); if (foldoutOpen) { GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); EditorGUILayout.HelpBox("_compatibleRaces[i] could not be located by the Dynamic Race Library", MessageType.Warning); GUIHelper.EndVerticalPadded(10); } } } } else { EditorGUILayout.HelpBox("Drag in compatible races at the top of this recipe and WardrobeSets for those races will show here", MessageType.Info); } GUIHelper.EndVerticalPadded(10); } GUILayout.Space(10); //the Arbitrary Recipes section GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); bool arbiOpen = OpenSlots["arbitraryRecipes"]; arbiOpen = EditorGUILayout.Foldout(OpenSlots["arbitraryRecipes"], "Arbitrary Recipes"); OpenSlots["arbitraryRecipes"] = arbiOpen; Rect dropArea = new Rect(); GUILayout.EndHorizontal(); if (arbiOpen) { GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); EditorGUILayout.HelpBox("Drop recipes in to this area to create a collection that is not a full outfit or connected to any given race, for example a 'Hair Styles' pack or 'Tattoos' pack.", MessageType.Info); dropArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true)); GUI.Box(dropArea, "Drag WardrobeRecipes here. " + recipesAddErrMsg); if (_arbitraryRecipes.Count > 0) { for (int i = 0; i < _arbitraryRecipes.Count; i++) { GUILayout.Space(2f); GUI.enabled = false; //we readonly to prevent typos Rect crfRect = GUILayoutUtility.GetRect(0.0f, EditorGUIUtility.singleLineHeight, GUILayout.ExpandWidth(true)); Rect crfDelRect = crfRect; crfRect.width = crfRect.width - 20f - 5f; crfDelRect.width = 20f + 2f; crfDelRect.x = crfRect.width + 20f + 10f; EditorGUI.TextField(crfRect, _arbitraryRecipes[i]); GUI.enabled = true; if (GUI.Button(crfDelRect, "X")) { _arbitraryRecipes.RemoveAt(i); changed = true; } } } GUIHelper.EndVerticalPadded(10); if (AddRecipesDropAreaGUI(ref recipesAddErrMsg, dropArea, _arbitraryRecipes)) { changed = true; } } return(changed); }
public bool OnColorGUI() { bool changed = false; int currentsharedcol = 0; string[] sharednames = new string[_recipe.sharedColors.Length]; if (_sharedColors) { GUIHelper.BeginVerticalPadded(2f, new Color(0.75f, 0.875f, 1f)); GUILayout.BeginHorizontal(); if (GUILayout.Toggle(true, "Use Shared Color") == false) { // Unshare color _overlayData.colorData = _overlayData.colorData.Duplicate(); _overlayData.colorData.name = OverlayColorData.UNSHARED; changed = true; } for (int i = 0; i < _recipe.sharedColors.Length; i++) { sharednames [i] = i + ": " + _recipe.sharedColors [i].name; if (_overlayData.colorData.GetHashCode() == _recipe.sharedColors [i].GetHashCode()) { currentsharedcol = i; } } int newcol = EditorGUILayout.Popup(currentsharedcol, sharednames); if (newcol != currentsharedcol) { changed = true; _overlayData.colorData = _recipe.sharedColors [newcol]; } GUILayout.EndHorizontal(); GUIHelper.EndVerticalPadded(2f); GUILayout.Space(2f); return(changed); } GUIHelper.BeginVerticalPadded(2f, new Color(0.75f, 0.875f, 1f)); GUILayout.BeginHorizontal(); if (_recipe.sharedColors.Length > 0) { if (GUILayout.Toggle(false, "Use Shared Color")) { // If we got rid of resetting the name above, we could try to match the last shared color? // Just set to default for now. _overlayData.colorData = _recipe.sharedColors [0]; changed = true; } } GUILayout.EndHorizontal(); bool showExtendedRanges = showExtendedRangeForOverlay == _overlayData; var newShowExtendedRanges = EditorGUILayout.Toggle("Show Extended Ranges", showExtendedRanges); if (showExtendedRanges != newShowExtendedRanges) { if (newShowExtendedRanges) { showExtendedRangeForOverlay = _overlayData; } else { showExtendedRangeForOverlay = null; } } for (int k = 0; k < _colors.Length; k++) { Color color; if (showExtendedRanges && k % 2 == 0) { Vector4 colorVector = new Vector4(_colors [k].color.r, _colors [k].color.g, _colors [k].color.b, _colors [k].color.a); colorVector = EditorGUILayout.Vector4Field(_colors [k].description, colorVector); color = new Color(colorVector.x, colorVector.y, colorVector.z, colorVector.w); } else { color = EditorGUILayout.ColorField(_colors [k].description, _colors [k].color); } if (color.r != _colors [k].color.r || color.g != _colors [k].color.g || color.b != _colors [k].color.b || color.a != _colors [k].color.a) { if (k % 2 == 0) { _overlayData.colorData.channelMask [k / 2] = color; } else { _overlayData.colorData.channelAdditiveMask [k / 2] = color; } changed = true; } } GUIHelper.EndVerticalPadded(2f); GUILayout.Space(2f); return(changed); }
public bool OnGUI(ref bool _dnaDirty, ref bool _textureDirty, ref bool _meshDirty) { bool changed = false; // Have to be able to assign a race on a new recipe. RaceData newRace = (RaceData)EditorGUILayout.ObjectField("RaceData", _recipe.raceData, typeof(RaceData), false); if (_recipe.raceData == null) { GUIHelper.BeginVerticalPadded(10, new Color(0.55f, 0.25f, 0.25f)); GUILayout.Label("Warning: No race data is set!"); GUIHelper.EndVerticalPadded(10); } if (_recipe.raceData != newRace) { _recipe.SetRace(newRace); changed = true; } if (GUILayout.Button("Remove Nulls")) { var newList = new List <SlotData>(_recipe.slotDataList.Length); foreach (var slotData in _recipe.slotDataList) { if (slotData != null) { newList.Add(slotData); } } _recipe.slotDataList = newList.ToArray(); changed |= true; _dnaDirty |= true; _textureDirty |= true; _meshDirty |= true; } if (_sharedColorsEditor.OnGUI(_recipe)) { changed = true; _textureDirty = true; } var added = (SlotDataAsset)EditorGUILayout.ObjectField("Add Slot", null, typeof(SlotDataAsset), false); if (added != null) { var slot = new SlotData(added); _recipe.MergeSlot(slot, false); changed |= true; _dnaDirty |= true; _textureDirty |= true; _meshDirty |= true; } for (int i = 0; i < _slotEditors.Count; i++) { var editor = _slotEditors[i]; if (editor == null) { GUILayout.Label("Empty Slot"); continue; } changed |= editor.OnGUI(ref _dnaDirty, ref _textureDirty, ref _meshDirty); if (editor.Delete) { _dnaDirty = true; _textureDirty = true; _meshDirty = true; _slotEditors.RemoveAt(i); _recipe.SetSlot(editor.idx, null); i--; changed = true; } } return(changed); }
public bool OnGUI(ref bool _dnaDirty, ref bool _textureDirty, ref bool _meshDirty) { bool delete; GUIHelper.FoldoutBar(ref _foldout, _name, out delete); if (!_foldout) { return(false); } Delete = delete; bool changed = false; GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); if (sharedOverlays) { EditorGUILayout.LabelField("Shared Overlays"); } else { var added = (OverlayDataAsset)EditorGUILayout.ObjectField("Add Overlay", null, typeof(OverlayDataAsset), false); if (added != null) { var newOverlay = new OverlayData(added); _overlayEditors.Add(new OverlayEditor(_recipe, _slotData, newOverlay)); _overlayData.Add(newOverlay); _dnaDirty = true; _textureDirty = true; _meshDirty = true; changed = true; } var addedSlot = (SlotDataAsset)EditorGUILayout.ObjectField("Add Slot", null, typeof(SlotDataAsset), false); if (addedSlot != null) { var newSlot = new SlotData(addedSlot); newSlot.SetOverlayList(_slotData.GetOverlayList()); _recipe.MergeSlot(newSlot, false); _dnaDirty = true; _textureDirty = true; _meshDirty = true; changed = true; } for (int i = 0; i < _overlayEditors.Count; i++) { var overlayEditor = _overlayEditors[i]; if (overlayEditor.OnGUI()) { _textureDirty = true; changed = true; } if (overlayEditor.Delete) { _overlayEditors.RemoveAt(i); _overlayData.RemoveAt(i); _textureDirty = true; changed = true; i--; } } for (int i = 0; i < _overlayEditors.Count; i++) { var overlayEditor = _overlayEditors[i]; if (overlayEditor.move > 0 && i + 1 < _overlayEditors.Count) { _overlayEditors[i] = _overlayEditors[i + 1]; _overlayEditors[i + 1] = overlayEditor; var overlayData = _overlayData[i]; _overlayData[i] = _overlayData[i + 1]; _overlayData[i + 1] = overlayData; overlayEditor.move = 0; _textureDirty = true; changed = true; continue; } if (overlayEditor.move < 0 && i > 0) { _overlayEditors[i] = _overlayEditors[i - 1]; _overlayEditors[i - 1] = overlayEditor; var overlayData = _overlayData[i]; _overlayData[i] = _overlayData[i - 1]; _overlayData[i - 1] = overlayData; overlayEditor.move = 0; _textureDirty = true; changed = true; continue; } } } GUIHelper.EndVerticalPadded(10); return(changed); }
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 bool OnGUI(UMAData.UMARecipe _recipe) { GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); _foldout = EditorGUILayout.Foldout(_foldout, "Shared Colors"); GUILayout.EndHorizontal(); if (_foldout) { bool changed = false; GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); EditorGUILayout.BeginHorizontal(); if (_recipe.sharedColors == null) { _recipe.sharedColors = new OverlayColorData[0]; } if (_recipe.sharedColors.Length == 0) { selectedChannelCount = EditorGUILayout.IntPopup("Channels", selectedChannelCount, names, channels); } else { selectedChannelCount = _recipe.sharedColors [0].channelMask.Length; } if (GUILayout.Button("Add Shared Color")) { List <OverlayColorData> sharedColors = new List <OverlayColorData> (); sharedColors.AddRange(_recipe.sharedColors); sharedColors.Add(new OverlayColorData(selectedChannelCount)); _recipe.sharedColors = sharedColors.ToArray(); changed = true; } if (GUILayout.Button("Save Collection")) { changed = true; } EditorGUILayout.EndHorizontal(); if (_ColorFoldouts.Length != _recipe.sharedColors.Length) { Array.Resize <bool> (ref _ColorFoldouts, _recipe.sharedColors.Length); } for (int i = 0; i < _recipe.sharedColors.Length; i++) { bool del = false; OverlayColorData ocd = _recipe.sharedColors [i]; GUIHelper.FoldoutBar(ref _ColorFoldouts [i], i + ": " + ocd.name, out del); if (del) { List <OverlayColorData> temp = new List <OverlayColorData> (); temp.AddRange(_recipe.sharedColors); temp.RemoveAt(i); _recipe.sharedColors = temp.ToArray(); // TODO: search the overlays and adjust the shared colors break; } if (_ColorFoldouts [i]) { if (ocd.name == null) { ocd.name = ""; } string NewName = EditorGUILayout.TextField("Name", ocd.name); if (NewName != ocd.name) { ocd.name = NewName; //changed = true; } Color NewChannelMask = EditorGUILayout.ColorField("Color Multiplier", ocd.channelMask [0]); if (ocd.channelMask [0] != NewChannelMask) { ocd.channelMask [0] = NewChannelMask; changed = true; } Color NewChannelAdditiveMask = EditorGUILayout.ColorField("Color Additive", ocd.channelAdditiveMask [0]); if (ocd.channelAdditiveMask [0] != NewChannelAdditiveMask) { ocd.channelAdditiveMask [0] = NewChannelAdditiveMask; changed = true; } for (int j = 1; j < ocd.channelMask.Length; j++) { NewChannelMask = EditorGUILayout.ColorField("Texture " + j + "multiplier", ocd.channelMask [j]); if (ocd.channelMask [j] != NewChannelMask) { ocd.channelMask [j] = NewChannelMask; changed = true; } NewChannelAdditiveMask = EditorGUILayout.ColorField("Texture " + j + " additive", ocd.channelAdditiveMask [j]); if (ocd.channelAdditiveMask [j] != NewChannelAdditiveMask) { ocd.channelAdditiveMask [j] = NewChannelAdditiveMask; changed = true; } } } } GUIHelper.EndVerticalPadded(10); return(changed); } return(false); }
public override bool OnGUI(string targetName, ref bool _dnaDirty, ref bool _textureDirty, ref bool _meshDirty) { bool changed = false; if (!OpenSlots.ContainsKey("wardrobeSet")) { OpenSlots.Add("wardrobeSet", true); } if (_sharedColorsEditor.OnGUI(_recipe)) { changed = true; } //if this is a backwards compatible DCS recipe (i.e. has SlotData AND a Wardrobe set) we need to show BOTH things //for this to really work youd need to be able to edit the WardrobeSet and have that modify the slotDataList //Hence the epic UpdateBackwardsCompatibleData method if (_recipe.slotDataList.Length > 0) { EditorGUILayout.HelpBox("This is a 'Backwards Compatible' DynamicCharacterAvatar recipe. The slots and overlays in the 'BackwardsCompatibleData' section will update as you change the items in the WardrobeSet.", MessageType.Info); } if (DrawWardrobeSetUI()) { changed = true; if (_recipe.slotDataList.Length > 0) { UpdateBackwardsCompatibleData(); } } if (_recipe.slotDataList.Length > 0) { if (!OpenSlots.ContainsKey("backwardsCompatibleData")) { OpenSlots.Add("backwardsCompatibleData", false); } GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); bool bcdfoldoutOpen = OpenSlots["backwardsCompatibleData"]; bcdfoldoutOpen = EditorGUILayout.Foldout(OpenSlots["backwardsCompatibleData"], "Backwards Compatible Data"); OpenSlots["backwardsCompatibleData"] = bcdfoldoutOpen; GUILayout.EndHorizontal(); if (bcdfoldoutOpen) { EditorGUI.BeginDisabledGroup(true); GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); for (int i = 0; i < _slotEditors.Count; i++) { var editor = _slotEditors[i]; if (editor == null) { GUILayout.Label("Empty Slot"); continue; } changed |= editor.OnGUI(ref _dnaDirty, ref _textureDirty, ref _meshDirty); if (editor.Delete) { _dnaDirty = true; _textureDirty = true; _meshDirty = true; _slotEditors.RemoveAt(i); _recipe.SetSlot(editor.idx, null); i--; changed = true; } } GUIHelper.EndVerticalPadded(10); EditorGUI.EndDisabledGroup(); } } return(changed); }
public bool OnGUI() { bool changed = false; if (_race != null) { if (_race.wardrobeSlots.Count > 0) { var context = UMAContext.FindInstance(); if (context == null) { var _errorMessage = "Editing a recipe requires a loaded scene with a valid UMAContext."; Debug.LogWarning(_errorMessage); } if (_wardrobeSet == null || context == null) { return(false); } GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); foreach (string wsl in _race.wardrobeSlots) { if (wsl == "None") { continue; } if (wsl == "FullOutfit" && _allowWardrobeCollectionSlot == false) { continue; } WardrobeSlotRecipePopup thisPicker = null; bool assignedPicker = false; for (int wsi = 0; wsi < _wardrobeSet.Count; wsi++) { if (_wardrobeSet[wsi].slot == wsl) { thisPicker = new WardrobeSlotRecipePopup(_race.raceName, wsl, _wardrobeSet[wsi].recipe); assignedPicker = true; break; } } if (!assignedPicker) //means there was nothing in the wardrobe set for it { thisPicker = new WardrobeSlotRecipePopup(_race.raceName, wsl, ""); } if (thisPicker.OnGUI()) { changed = true; if (thisPicker.RecipeName != "None" && thisPicker.RecipeName != "") { bool contained = false; for (int i = 0; i < _wardrobeSet.Count; i++) { if (_wardrobeSet[i].slot == wsl) { _wardrobeSet[i].recipe = thisPicker.RecipeName; contained = true; break; } } if (!contained) { _wardrobeSet.Add(new WardrobeSettings(wsl, thisPicker.RecipeName)); } } else { for (int i = 0; i < _wardrobeSet.Count; i++) { if (_wardrobeSet[i].slot == wsl) { _wardrobeSet.RemoveAt(i); break; } } } } } if (WardrobeSet.Count > 0) { if (GUILayout.Button(new GUIContent("UpdateSharedColors", "Automatically adds any shared colors defined in the selected recipes to this recipes SharedColors"))) { for (int i = 0; i < _wardrobeSet.Count; i++) { changed = AddSharedColorsFromRecipe(_wardrobeSet[i].recipe, _recipe) == true ? true : changed; } } } GUIHelper.EndVerticalPadded(10); } } return(changed); }
public bool OnGUI(ref bool _dnaDirty, ref bool _textureDirty, ref bool _meshDirty) { bool delete; GUIHelper.FoldoutBar(ref _foldout, _name, out delete); if (!_foldout) { return(false); } Delete = delete; bool changed = false; GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); var added = (OverlayData)EditorGUILayout.ObjectField("Add Overlay", null, typeof(OverlayData), false); if (added != null) { _overlayEditors.Add(new OverlayEditor(_slotData, added)); _overlayData.Add(added); _dnaDirty = true; _textureDirty = true; _meshDirty = true; changed = true; } for (int i = 0; i < _overlayEditors.Count; i++) { var overlayEditor = _overlayEditors [i]; if (overlayEditor.OnGUI()) { _textureDirty = true; changed = true; } if (overlayEditor.Delete) { _overlayEditors.RemoveAt(i); _overlayData.RemoveAt(i); _textureDirty = true; changed = true; i--; } } for (int i = 0; i < _overlayEditors.Count; i++) { var overlayEditor = _overlayEditors[i]; if (overlayEditor.move > 0) { _overlayEditors.MoveElementUpAt(i); _overlayData.MoveElementUpAt(i); overlayEditor.move = 0; _textureDirty = true; changed = true; continue; } if (overlayEditor.move < 0 && i + 1 > 0) { _overlayEditors.MoveElementDownAt(i); _overlayData.MoveElementDownAt(i); overlayEditor.move = 0; _textureDirty = true; changed = true; continue; } } GUIHelper.EndVerticalPadded(10); return(changed); }
public bool OnGUI() { bool changed = false; if (_race != null) { if (_race.wardrobeSlots.Count > 0) { var context = UMAContext.FindInstance(); if (context == null) { var _errorMessage = "Editing a recipe requires a loaded scene with a valid UMAContext."; Debug.LogWarning(_errorMessage); } if (_wardrobeSet == null || context == null) { return(false); } GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); if (_allowWardrobeCollectionSlot) { var wcRecipesForRace = context.dynamicCharacterSystem.GetRecipesForRaceSlot(_race.raceName, "WardrobeCollection"); var wcGroupDict = new Dictionary <string, List <string> >(); //for 'Standard Assets' we need to do some kind of get Types thing I think because we then need to use reflection to get the wardrobeSlot field //how can we get what we want here when WardrobeCollections dont exist in Standard Assets (if 'StandardAssets' has been moved there) for (int i = 0; i < wcRecipesForRace.Count; i++) { Type wcType = wcRecipesForRace[i].GetType(); if (wcType.ToString() == "UMAWardrobeCollection") { FieldInfo wcRecipeSlotField = wcType.GetField("wardrobeSlot", BindingFlags.Public | BindingFlags.Instance); var wcRecipeSlot = (string)wcRecipeSlotField.GetValue(wcRecipesForRace[i]); if (!wcGroupDict.ContainsKey(wcRecipeSlot)) { wcGroupDict.Add(wcRecipeSlot, new List <string>()); } wcGroupDict[wcRecipeSlot].Add(wcRecipesForRace[i].name); } } if (wcGroupDict.Count > 0) { EditorGUILayout.LabelField("WardrobeCollections"); EditorGUI.indentLevel++; foreach (KeyValuePair <string, List <string> > kp in wcGroupDict) { var thisPopupVals = new List <string>(); thisPopupVals.Add("None"); thisPopupVals.AddRange(kp.Value); var selected = 0; var prevRecipe = ""; //if one of the recipes in the wardrobe set is one of these then its selected for (int pvi = 0; pvi < thisPopupVals.Count; pvi++) { for (int wsi = 0; wsi < _wardrobeSet.Count; wsi++) { if (thisPopupVals[pvi] == _wardrobeSet[wsi].recipe) { prevRecipe = _wardrobeSet[wsi].recipe; selected = pvi; break; } } } EditorGUI.BeginChangeCheck(); var newSelected = EditorGUILayout.Popup(kp.Key, selected, thisPopupVals.ToArray()); if (EditorGUI.EndChangeCheck()) { for (int wsi = 0; wsi < _wardrobeSet.Count; wsi++) { if (_wardrobeSet[wsi].recipe == prevRecipe) { //we need to remove the wardrobeSettings that has prevRecipe as its value from _wardrobeSettings if (newSelected == 0) { _wardrobeSet.RemoveAt(wsi); } else { //we need to make wardrobeSettings that has prevRecipe have the new value _wardrobeSet[wsi].recipe = thisPopupVals[newSelected]; } } } changed = true; } } EditorGUI.indentLevel--; EditorGUILayout.Space(); EditorGUILayout.LabelField("WardrobeSlots"); EditorGUI.indentLevel++; } } foreach (string wsl in _race.wardrobeSlots) { if (wsl == "None") { continue; } if (wsl == "FullOutfit" && _allowWardrobeCollectionSlot == false) { continue; } WardrobeSlotRecipePopup thisPicker = null; bool assignedPicker = false; for (int wsi = 0; wsi < _wardrobeSet.Count; wsi++) { if (_wardrobeSet[wsi].slot == wsl) { thisPicker = new WardrobeSlotRecipePopup(_race.raceName, wsl, _wardrobeSet[wsi].recipe); assignedPicker = true; break; } } if (!assignedPicker) //means there was nothing in the wardrobe set for it { thisPicker = new WardrobeSlotRecipePopup(_race.raceName, wsl, ""); } if (thisPicker.OnGUI()) { changed = true; if (thisPicker.RecipeName != "None" && thisPicker.RecipeName != "") { bool contained = false; for (int i = 0; i < _wardrobeSet.Count; i++) { if (_wardrobeSet[i].slot == wsl) { _wardrobeSet[i].recipe = thisPicker.RecipeName; contained = true; break; } } if (!contained) { _wardrobeSet.Add(new WardrobeSettings(wsl, thisPicker.RecipeName)); } } else { for (int i = 0; i < _wardrobeSet.Count; i++) { if (_wardrobeSet[i].slot == wsl) { _wardrobeSet.RemoveAt(i); break; } } } } } if (_allowWardrobeCollectionSlot) { EditorGUI.indentLevel--; } if (WardrobeSet.Count > 0) { EditorGUILayout.Space(); if (GUILayout.Button(new GUIContent("UpdateSharedColors", "Automatically adds any shared colors defined in the selected recipes to this recipes SharedColors"))) { for (int i = 0; i < _wardrobeSet.Count; i++) { changed = AddSharedColorsFromRecipe(_wardrobeSet[i].recipe, _recipe) == true ? true : changed; } } } GUIHelper.EndVerticalPadded(10); } } return(changed); }
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(); }