コード例 #1
0
        //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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
            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);
            }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
ファイル: pDCSRecipeEditor.cs プロジェクト: effofxprime/UMA-1
            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);
            }
コード例 #9
0
ファイル: pDCSRecipeEditor.cs プロジェクト: effofxprime/UMA-1
            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);
            }
コード例 #10
0
ファイル: CharacterBaseEditor.cs プロジェクト: Kinyajuu/UMA
        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);
        }
コード例 #11
0
ファイル: pDCSRecipeEditor.cs プロジェクト: grendelbiter/UMA
            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);
            }
コード例 #12
0
 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();
 }