public override void OnInspectorGUI()
        {
            if (!initialized)
            {
                Init();
            }

            serializedObject.Update();
            GUILayout.Space(5);
            var dnaHeaderRect = EditorGUILayout.GetControlRect();

            GUIHelper.ToolbarStyleHeader(dnaHeaderRect, new GUIContent("DYNAMIC DNA"), _help, ref _helpIsExpanded);

            var importBtnRect = new Rect(dnaHeaderRect.xMax - 40f, dnaHeaderRect.yMin + 2f, 20f, EditorGUIUtility.singleLineHeight);

            _importToolsExpanded = GUI.Toggle(importBtnRect, _importToolsExpanded, importContent, _importStyle);

            GUIHelper.BeginVerticalPadded(3, new Color(0.75f, 0.875f, 1f, 0.3f));

            SerializedProperty Names = serializedObject.FindProperty("Names");

            if (_importToolsExpanded)
            {
                DrawImportNamesTools();
            }

            SerializedProperty dnaTypeHash = serializedObject.FindProperty("dnaTypeHash");

            Rect hashEditorRect = GUILayoutUtility.GetRect(0.0f, EditorGUIUtility.singleLineHeight, GUILayout.ExpandWidth(true));
            var  hashLabelRect  = hashEditorRect;

            hashLabelRect.xMax = hashEditorRect.xMax / 3;
            var hashBtnRect = hashEditorRect;

            hashBtnRect.xMin = hashLabelRect.xMax + (EditorGUI.indentLevel * 20);
            hashBtnRect.xMax = hashBtnRect.xMin + 50 + (EditorGUI.indentLevel * 20);
            var hashFieldRect = hashEditorRect;

            hashFieldRect.xMin = hashBtnRect.xMax - ((EditorGUI.indentLevel * 20) - 10);
            if (editTypeHashEnabled)
            {
                EditorGUI.LabelField(hashLabelRect, new GUIContent(dnaTypeHash.displayName, _dnaTypehashTooltip));
                if (GUI.Button(hashBtnRect, new GUIContent("Save", _dnaTypehashTooltip)))
                {
                    editTypeHashEnabled = false;
                }
                var originalDnaTypeHash = dnaTypeHash;
                EditorGUI.BeginChangeCheck();
                EditorGUI.PropertyField(hashFieldRect, dnaTypeHash, new GUIContent(""));
                if (EditorGUI.EndChangeCheck())
                {
                    //we MUST NOT let this have the same TypeHash as UMADnaHumanoid or UMADnaTutorial, so if people randomly choose that value- dont assign it
                    if (dnaTypeHash.intValue == UMAUtils.StringToHash("UMADnaHumanoid") || dnaTypeHash.intValue == UMAUtils.StringToHash("UMADnaTutorial"))
                    {
                        Debug.LogWarning("You are trying to set a DynamicDNA to the same hash as a UMADnaHumanoid or UMADnaTutorial dna- this is not allowed");
                        dnaTypeHash = originalDnaTypeHash;
                    }
                    else
                    {
                        serializedObject.ApplyModifiedProperties();
                    }
                }
            }
            else
            {
                EditorGUI.LabelField(hashLabelRect, new GUIContent(dnaTypeHash.displayName, _dnaTypehashTooltip));
                if (GUI.Button(hashBtnRect, new GUIContent("Edit", _dnaTypehashTooltip)))
                {
                    if (EditorUtility.DisplayDialog("Really Change the Hash?", "If you change the DNA Assets hash, any recipes that use this DNA will need to be inspected so they update to the new value. Are you sure?", "Yes", "Cancel"))
                    {
                        editTypeHashEnabled = true;
                    }
                }
                EditorGUI.BeginDisabledGroup(true);
                EditorGUI.PropertyField(hashFieldRect, dnaTypeHash, new GUIContent(""));
                EditorGUI.EndDisabledGroup();
            }
            EditorGUILayout.Space();

            if (Names.arraySize == 0)
            {
                EditorGUILayout.HelpBox("Define your the names for your dna by adding them below", MessageType.Info);
            }
            //ACTUAL NAMES LIST
            _dnaNameList.DoLayoutList();
            //ADD NEW NAME BUTTON
            //Moved Add controls into the Reorderable list footer for consistancy

            //message that the name exists
            if (!string.IsNullOrEmpty(newDNAName) && canAddNewDNAName == false)
            {
                EditorGUILayout.HelpBox("That name is already in use.", MessageType.Warning);
            }

            //Clear out indices that have been added to the remove list.
            for (int i = _dnaNameList.serializedProperty.arraySize - 1; i >= 0; i--)
            {
                if (_removeList.Contains(i))
                {
                    _dnaNameList.serializedProperty.DeleteArrayElementAtIndex(i);
                }
            }
            _removeList.Clear();


            serializedObject.ApplyModifiedProperties();

            GUIHelper.EndVerticalPadded(3);
            GUILayout.Space(5);
        }
예제 #2
0
 public void SelectNewSlotMesh()
 {
     forcedSlotBones = false;
     UMAUtils.DestroySceneObject(SlotGO);
     SetPage(1);
 }
        /// <summary>
        /// Draws a DNAEvaluator with inline styling
        /// </summary>
        /// <param name="position"></param>
        /// <param name="property"></param>
        /// <param name="label"></param>
        public void DoFieldsInline(Rect position, SerializedProperty property)
        {
            CheckDynamicDNAPlugin(property);

            Init();

            var prevIndent = EditorGUI.indentLevel;

            EditorGUI.indentLevel = 0;

            Rect calcOptionRect = Rect.zero;

            if (_drawCalcOption)
            {
                calcOptionRect = new Rect(position.xMin, position.yMin, _calcOptionWidth, EditorGUIUtility.singleLineHeight);
                position.xMin  = calcOptionRect.xMax;
            }
            var calcOptionProp      = property.FindPropertyRelative(CALCOPTIONPROPERTY);
            var dnaNameProp         = property.FindPropertyRelative(DNANAMEPROPERTY);
            var dnaNameHashProp     = property.FindPropertyRelative(DNANAMEHASHPROPERTY);
            var evaluatorProp       = property.FindPropertyRelative(EVALUATORPROPERTY);
            var intensityProp       = property.FindPropertyRelative(MULTIPLIERPROPERTY);
            var fieldbaseRatio      = (position.width - _multiplierLabelWidth) / (_dnaToEvaluatorRatio.x + _dnaToEvaluatorRatio.y);
            var dnafieldWidth       = fieldbaseRatio * _dnaToEvaluatorRatio.x;
            var evaluatorFieldWidth = fieldbaseRatio * _dnaToEvaluatorRatio.y;

            position.height = EditorGUIUtility.singleLineHeight;            //theres a space at the bottom so cut that off

            var dnaNameRect    = new Rect(position.xMin + _padding, position.yMin, dnafieldWidth - (_padding * 2), position.height);
            var evaluatorRect  = new Rect(dnaNameRect.xMax + (_padding * 2), position.yMin, evaluatorFieldWidth - (_padding * 2), position.height);
            var multiplierRect = new Rect(evaluatorRect.xMax + (_padding * 2), position.yMin, _multiplierLabelWidth - (_padding * 2), position.height);

            if (_drawCalcOption)
            {
                calcOptionProp.enumValueIndex = EditorGUI.Popup(calcOptionRect, calcOptionProp.enumValueIndex, _calcOptionMiniLabels);
            }
            EditorGUI.BeginChangeCheck();
            if (_dynamicDNAPlugin == null)
            {
                EditorGUI.PropertyField(dnaNameRect, dnaNameProp, GUIContent.none);
            }
            else
            {
                DynamicDNAConverterControllerInspector.DNANamesPopup(dnaNameRect, dnaNameProp, dnaNameProp.stringValue, _dynamicDNAPlugin.converterController.DNAAsset);
            }
            if (EditorGUI.EndChangeCheck())
            {
                if (!string.IsNullOrEmpty(dnaNameProp.stringValue))
                {
                    dnaNameHashProp.intValue = UMAUtils.StringToHash(dnaNameProp.stringValue);
                }
                else
                {
                    dnaNameHashProp.intValue = -1;
                }
            }
            EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(dnaNameProp.stringValue));
            EditorGUI.BeginChangeCheck();
            EditorGUI.PropertyField(evaluatorRect, evaluatorProp, GUIContent.none);
            if (EditorGUI.EndChangeCheck())
            {
                InspectorUtlity.RepaintAllInspectors();
                GUI.changed = true;
            }
            EditorGUI.PropertyField(multiplierRect, intensityProp, GUIContent.none);
            EditorGUI.EndDisabledGroup();

            EditorGUI.indentLevel = prevIndent;
        }
예제 #4
0
        public void Initialize()
        {
            blinkDelay = Random.Range(minBlinkDelay, maxBlinkDelay);

            if (Camera.main != null)
            {
                _mainCameraTransform = Camera.main.transform;
            }


            if ((expressionSet != null) && (umaData != null) && (umaData.skeleton != null))
            {
                Transform jaw  = null;
                Transform neck = null;
                Transform head = null;



                if (GenericRig)
                {
                    if (overrideMecanimJaw)
                    {
                        jawHash = UMAUtils.StringToHash(GenericJawBone);
                        jaw     = umaData.skeleton.GetBoneTransform(jawHash);
                    }

                    if (overrideMecanimNeck)
                    {
                        neckHash = UMAUtils.StringToHash(GenericNeckBone);
                        neck     = umaData.skeleton.GetBoneTransform(neckHash);
                    }

                    if (overrideMecanimHead)
                    {
                        headHash = UMAUtils.StringToHash(GenericHeadBone);
                        head     = umaData.skeleton.GetBoneTransform(headHash);
                    }
                }
                else
                {
                    if (umaData.animator != null)
                    {
                        jaw = umaData.animator.GetBoneTransform(HumanBodyBones.Jaw);
                        if (jaw != null)
                        {
                            jawHash = UMAUtils.StringToHash(jaw.name);
                        }

                        neck = umaData.animator.GetBoneTransform(HumanBodyBones.Neck);
                        if (neck != null)
                        {
                            neckHash = UMAUtils.StringToHash(neck.name);
                        }

                        head = umaData.animator.GetBoneTransform(HumanBodyBones.Head);
                        if (head != null)
                        {
                            headHash = UMAUtils.StringToHash(head.name);
                        }
                    }
                }
                if (overrideMecanimJaw && jaw == null)
                {
                    if (Debug.isDebugBuild)
                    {
                        Debug.Log("Jaw bone not found, but jaw override is requested.");
                    }
                    return;
                }
                if (overrideMecanimNeck && neck == null)
                {
                    if (Debug.isDebugBuild)
                    {
                        Debug.Log("Neck bone not found, but neck override is requested.");
                    }
                    return;
                }
                if (overrideMecanimHead && head == null)
                {
                    if (Debug.isDebugBuild)
                    {
                        Debug.Log("Head bone not found, but head override is requested.");
                    }
                    return;
                }
                if (overrideMecanimJaw && jaw == null)
                {
                    if (Debug.isDebugBuild)
                    {
                        Debug.Log("Jaw bone not found, but jaw override is requested.");
                    }
                    return;
                }
                initialized = true;
            }
        }
        private void SetupSwingBones(List <string> swingBoneNames)
        {
            try
            {
                SoftJointLimit zeroJointLimit  = new SoftJointLimit();
                SoftJointLimit sixtyJointLimit = new SoftJointLimit();
                sixtyJointLimit.limit = 60;

                SwingBones = new Transform[swingBoneNames.Count];

                // Add rigidbody, colliders, characterJoints to bone.
                for (int i = 0; i < swingBoneNames.Count; i++)
                {
                    string    s = swingBoneNames[i];
                    Transform t = umaData.skeleton.GetBoneTransform(UMAUtils.StringToHash(s));
                    SwingBones[i] = t;

                    if (t == null)
                    {
                        Debug.Log("Transform for Swingbone " + s + " not found");
                        continue;
                    }

                    GameObject go = t.gameObject;
                    go.layer = 8;     // our ragdoll layer

                    if (go.GetComponent <Rigidbody>() != null)
                    {
                        continue;
                    }
                    Rigidbody r = go.AddComponent <Rigidbody>();
                    r.isKinematic = false;

                    // Only add gravity to the last link in the chain (the "Pendulum"). Helps prevent physics explosion.
                    if (i == SwingBones.Length - 1)
                    {
                        // this is the Pendulum. Needs gravity. Need script to apply global force
                        r.useGravity = true;
                        //
                        r.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
                        UMAGlobalForceApplier GFA = go.AddComponent <UMAGlobalForceApplier>();
                        GFA.ApplyGlobalForces  = ApplyGlobalForces;
                        GFA.ForceMultiplier    = ForceMultiplier;
                        GFA.MinGlobalForce     = MinGlobalForce;
                        GFA.MaxGlobalForce     = MaxGlobalForce;
                        GFA.MovementTracker    = AnchorBone;
                        GFA.AttachedRigidBody  = r;
                        GFA.parentPosLastFrame = AnchorBone.position;
                    }
                    else
                    {
                        r.useGravity = false;
                    }

                    r.maxAngularVelocity       = 4;
                    r.maxDepenetrationVelocity = 3;
                    r.mass        = SwingMass;
                    r.drag        = SwingDrag;
                    r.angularDrag = SwingAngularDrag;

                    if (FreezePositions)
                    {
                        r.constraints = RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezePositionY | RigidbodyConstraints.FreezePositionZ;
                    }

                    SphereCollider sc = t.gameObject.AddComponent <SphereCollider>();
                    sc.radius = SwingRadius;

                    CharacterJoint c = t.gameObject.AddComponent <CharacterJoint>();

                    c.autoConfigureConnectedAnchor = true;
                    if (i == 0)
                    {
                        c.connectedBody = AnchorBone.gameObject.GetComponent <Rigidbody>();
                    }
                    else
                    {
                        c.connectedBody = SwingBones[i - 1].gameObject.GetComponent <Rigidbody>();
                    }
                    c.lowTwistLimit  = zeroJointLimit;
                    c.highTwistLimit = zeroJointLimit;
                    c.swing1Limit    = sixtyJointLimit;
                    c.swing2Limit    = sixtyJointLimit;
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);
            }
        }
        /// <summary>
        /// Generates a temporary item of type T. It then adds a new DownloadingAssetItem to downloadingItems that contains a refrence to this created temp asset and the name of the asset that it should be replaced by once the given assetbundle has completed downloading.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="requiredAssetName"></param>
        /// <param name="requiredAssetNameHash"></param>
        /// <param name="containingBundle"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        public T AddDownloadItem <T>(string requiredAssetName, int?requiredAssetNameHash, string containingBundle, Delegate callback = null) where T : UnityEngine.Object
        {
            T thisTempAsset = null;

            if (downloadingItems.Find(item => item.requiredAssetName == requiredAssetName) == null)
            {
                if (requiredAssetNameHash == null)
                {
                    requiredAssetNameHash = UMAUtils.StringToHash(requiredAssetName);
                }
                thisTempAsset = GetTempAsset <T>();
                if (typeof(T) == typeof(RaceData))
                {
                    (thisTempAsset as RaceData).raceName = requiredAssetName;
                    (thisTempAsset as RaceData).name     = requiredAssetName;
                }
                else if (typeof(T) == typeof(SlotDataAsset))
                {
                    (thisTempAsset as SlotDataAsset).name     = requiredAssetName;
                    (thisTempAsset as SlotDataAsset).slotName = requiredAssetName;
                    (thisTempAsset as SlotDataAsset).nameHash = (int)requiredAssetNameHash;
                }
                else if (typeof(T) == typeof(OverlayDataAsset))
                {
                    (thisTempAsset as OverlayDataAsset).name        = requiredAssetName;
                    (thisTempAsset as OverlayDataAsset).overlayName = requiredAssetName;
                    (thisTempAsset as OverlayDataAsset).nameHash    = (int)requiredAssetNameHash;
                }
                else if (typeof(T) == typeof(UMATextRecipe))
                {
                    //now that wardrobeRecipes have their own type, we can assume an UMATextRecipe is a full character recipe
                    thisTempAsset.name = requiredAssetName;
                }
                else if (typeof(T) == typeof(UMAWardrobeRecipe))
                {
                    (thisTempAsset as UMAWardrobeRecipe).recipeType      = "Wardrobe";
                    (thisTempAsset as UMAWardrobeRecipe).wardrobeSlot    = AssetBundleManager.AssetBundleIndexObject.AssetWardrobeSlot(containingBundle, requiredAssetName);
                    (thisTempAsset as UMAWardrobeRecipe).Hides           = AssetBundleManager.AssetBundleIndexObject.AssetWardrobeHides(containingBundle, requiredAssetName);
                    (thisTempAsset as UMAWardrobeRecipe).compatibleRaces = AssetBundleManager.AssetBundleIndexObject.AssetWardrobeCompatibleWith(containingBundle, requiredAssetName);
                    thisTempAsset.name = requiredAssetName;
                }
                else if (typeof(T) == typeof(UMAWardrobeCollection))
                {
                    (thisTempAsset as UMAWardrobeCollection).recipeType      = "WardrobeCollection";
                    (thisTempAsset as UMAWardrobeCollection).wardrobeSlot    = AssetBundleManager.AssetBundleIndexObject.AssetWardrobeCollectionSlot(containingBundle, requiredAssetName);
                    (thisTempAsset as UMAWardrobeCollection).compatibleRaces = AssetBundleManager.AssetBundleIndexObject.AssetWardrobeCollectionCompatibleWith(containingBundle, requiredAssetName);
                    thisTempAsset.name = requiredAssetName;
                }
                else if (typeof(T) == typeof(RuntimeAnimatorController))
                {
                    (thisTempAsset as RuntimeAnimatorController).name = requiredAssetName;
                }
                else
                {
                    thisTempAsset.name = requiredAssetName;
                }
                var thisDlItem = new DownloadingAssetItem(requiredAssetName, thisTempAsset, containingBundle, callback);
                downloadingItems.Add(thisDlItem);
            }
            else
            {
                DownloadingAssetItem dlItem = null;
                if (downloadingItems.Find(item => item.requiredAssetName == requiredAssetName) != null)
                {
                    dlItem = downloadingItems.Find(item => item.requiredAssetName == requiredAssetName);
                }
                if (dlItem != null)
                {
                    //Debug.LogWarning("DownloadingAssetsList already had entry for " + requiredAssetName + " as type " + dlItem.tempAsset.GetType().ToString() + " new request wanted it as type " + typeof(T) + " and its callback was " + dlItem.dynamicCallback[0].Method.Name);
                    if (callback != null)
                    {
                        if (!dlItem.dynamicCallback.Contains(callback))
                        {
                            dlItem.dynamicCallback.Add(callback);
                        }
                    }
                    thisTempAsset = dlItem.tempAsset as T;
                }
                else
                {
                    Debug.LogWarning("Could not get TempAsset for " + requiredAssetName);
                }
            }
            return(thisTempAsset);
        }
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            int startingIndent = EditorGUI.indentLevel;

            EditorGUI.BeginProperty(position, label, property);
            var    valR        = new Rect(position.xMin, position.yMin, position.width, EditorGUIUtility.singleLineHeight);
            string betterLabel = label.text;

            if (property.FindPropertyRelative("property").enumDisplayNames[property.FindPropertyRelative("property").enumValueIndex] != "")
            {
                betterLabel += " (" + property.FindPropertyRelative("property").enumDisplayNames[property.FindPropertyRelative("property").enumValueIndex] + ")";
            }
            List <string> boneNames = new List <string>();

            if (bonesInSkeleton != null)
            {
                boneNames = new List <string>(bonesInSkeleton);
            }
            else
            {
                boneNames = new List <string>(hashNames);
            }
            string thisHashName  = property.FindPropertyRelative("hashName").stringValue;
            int    hashNameIndex = boneNames.IndexOf(thisHashName);

            if (hashNameIndex == -1 && bonesInSkeleton != null)
            {
                boneNames.Insert(0, thisHashName + " (missing)");
                hashNameIndex = 0;
                var warningRect    = new Rect((valR.xMin), valR.yMin, 20f, valR.height);
                var warningIconGUI = new GUIContent("", thisHashName + " was not a bone in the Avatars Skeleton. Please choose another bone for this modifier or delete it.");
                warningIconGUI.image = warningIcon;
                betterLabel         += " (missing)";
                GUI.Label(warningRect, warningIconGUI, warningStyle);
            }
            property.isExpanded = EditorGUI.Foldout(valR, property.isExpanded, betterLabel, true);
            if (property.isExpanded)
            {
                EditorGUI.indentLevel++;
                valR = new Rect(valR.xMin, valR.yMax + padding, valR.width, EditorGUIUtility.singleLineHeight);
                if (boneNames.Count > 0)
                {
                    int newHashNameIndex = hashNameIndex;
                    EditorGUI.BeginChangeCheck();
                    newHashNameIndex = EditorGUI.Popup(valR, "Hash Name", hashNameIndex, boneNames.ToArray());
                    if (EditorGUI.EndChangeCheck())
                    {
                        if (newHashNameIndex != hashNameIndex)
                        {
                            property.FindPropertyRelative("hashName").stringValue = boneNames[newHashNameIndex];
                            property.FindPropertyRelative("hash").intValue        = UMAUtils.StringToHash(boneNames[newHashNameIndex]);
                            property.serializedObject.ApplyModifiedProperties();
                        }
                    }
                }
                else
                {
                    EditorGUI.PropertyField(valR, property.FindPropertyRelative("hashName"));
                }
                valR = new Rect(valR.xMin, valR.yMax + padding, valR.width, EditorGUIUtility.singleLineHeight);
                EditorGUI.PropertyField(valR, property.FindPropertyRelative("property"));
                valR = new Rect(valR.xMin, valR.yMax + padding, valR.width, EditorGUIUtility.singleLineHeight);
                var valXR = valR;
                var valYR = valR;
                var valZR = valR;
                valXR.width = valYR.width = valZR.width = valR.width / 3;
                valYR.x     = valYR.x + valXR.width;
                valZR.x     = valZR.x + valXR.width + valYR.width;
                SerializedProperty subValsToOpen = null;
                var valuesX = property.FindPropertyRelative("valuesX");
                var valuesY = property.FindPropertyRelative("valuesY");
                var valuesZ = property.FindPropertyRelative("valuesZ");
                if (valuesX.isExpanded)
                {
                    var valXRB = valXR;
                    valXRB.x     = valXRB.x + (EditorGUI.indentLevel * 10f);
                    valXRB.width = valXRB.width - (EditorGUI.indentLevel * 10f);
                    EditorGUI.DrawRect(valXRB, new Color32(255, 255, 255, 100));
                }
                valuesX.isExpanded = EditorGUI.Foldout(valXR, valuesX.isExpanded, "ValuesX", true);
                if (valuesX.isExpanded)
                {
                    valuesY.isExpanded = false;
                    valuesZ.isExpanded = false;
                    subValsToOpen      = valuesX;
                }
                if (valuesY.isExpanded)
                {
                    EditorGUI.DrawRect(valYR, new Color32(255, 255, 255, 100));
                }
                valuesY.isExpanded = EditorGUI.Foldout(valYR, valuesY.isExpanded, "ValuesY", true);
                if (valuesY.isExpanded)
                {
                    valuesX.isExpanded = false;
                    valuesZ.isExpanded = false;
                    subValsToOpen      = valuesY;
                }
                if (valuesZ.isExpanded)
                {
                    EditorGUI.DrawRect(valZR, new Color32(255, 255, 255, 100));
                }
                valuesZ.isExpanded = EditorGUI.Foldout(valZR, valuesZ.isExpanded, "ValuesZ", true);
                if (valuesZ.isExpanded)
                {
                    valuesX.isExpanded = false;
                    valuesY.isExpanded = false;
                    subValsToOpen      = valuesZ;
                }
                if (subValsToOpen != null)
                {
                    valR       = new Rect(valR.xMin, valR.yMax + padding + 4f, valR.width, EditorGUIUtility.singleLineHeight);
                    valR.width = valR.width - 30;
                    var boxR1 = valR;
                    boxR1.x      = boxR1.x + EditorGUI.indentLevel * 10f;
                    boxR1.y      = boxR1.y - 6;
                    boxR1.height = boxR1.height + 12;
                    //topbox
                    EditorGUI.DrawRect(boxR1, new Color32(255, 255, 255, 100));
                    var valSXR = valR;
                    var valSYR = valR;
                    var valSZR = valR;
                    valSXR.width = valSYR.width = valSZR.width = valR.width / 3;
                    valSYR.x     = valSYR.x + valSXR.width;
                    valSZR.x     = valSZR.x + valSXR.width + valSYR.width;
                    var subValuesVal = subValsToOpen.FindPropertyRelative("val");
                    var subValuesMin = subValsToOpen.FindPropertyRelative("min");
                    var subValuesMax = subValsToOpen.FindPropertyRelative("max");
                    var valSXRF      = valSXR;
                    valSXRF.x     = valSXRF.x + 38f;
                    valSXRF.width = valSXRF.width - 35f;
                    if (!enableSkelModValueEditing)
                    {
                        EditorGUI.BeginDisabledGroup(true);
                    }
                    EditorGUI.LabelField(valSXR, "Value");
                    subValuesVal.FindPropertyRelative("value").floatValue = EditorGUI.FloatField(valSXRF, subValuesVal.FindPropertyRelative("value").floatValue);
                    subValuesVal.serializedObject.ApplyModifiedProperties();
                    if (!enableSkelModValueEditing)
                    {
                        EditorGUI.EndDisabledGroup();
                    }
                    var valSYRF = valSYR;
                    valSYRF.x     = valSYRF.x + 30f;
                    valSYRF.width = valSYRF.width - 30f;
                    EditorGUI.LabelField(valSYR, "Min");
                    subValuesMin.floatValue = EditorGUI.FloatField(valSYRF, subValuesMin.floatValue);
                    var valSZRF = valSZR;
                    valSZRF.x     = valSZRF.x + 30f;
                    valSZRF.width = valSZRF.width - 30f;
                    EditorGUI.LabelField(valSZR, "Max");
                    subValuesMax.floatValue = EditorGUI.FloatField(valSZRF, subValuesMax.floatValue);
                    var thisModifiersProp = subValuesVal.FindPropertyRelative("modifiers");
                    var modifiersi        = thisModifiersProp.arraySize;
                    valR = new Rect(valR.xMin, valR.yMax + padding + 4f, valR.width, EditorGUIUtility.singleLineHeight);
                    var boxR = valR;
                    boxR.y      = boxR.y - 2f;
                    boxR.x      = boxR.x + EditorGUI.indentLevel * 10f;
                    boxR.height = boxR.height + 6f + ((EditorGUIUtility.singleLineHeight + padding) * (modifiersi + 1));
                    //bottombox
                    EditorGUI.DrawRect(boxR, new Color32(255, 255, 255, 100));
                    EditorGUI.LabelField(valR, "Value Modifiers");
                    for (int i = 0; i < modifiersi; i++)
                    {
                        valR = new Rect(valR.xMin, valR.yMax + padding, valR.width, EditorGUIUtility.singleLineHeight);
                        var propsR = valR;
                        propsR.width = valR.width;
                        var valRBut = new Rect((propsR.width + 35f), valR.y, 20f, EditorGUIUtility.singleLineHeight);
                        thisSpValDrawer.OnGUI(propsR, thisModifiersProp.GetArrayElementAtIndex(i), new GUIContent(""));
                        if (GUI.Button(valRBut, "X"))
                        {
                            thisModifiersProp.DeleteArrayElementAtIndex(i);
                        }
                    }
                    var addBut = new Rect(valR.xMin, valR.yMax + padding, valR.width, EditorGUIUtility.singleLineHeight);
                    addBut.x     = addBut.xMax - 35f;
                    addBut.width = 60f;
                    if (GUI.Button(addBut, "Add"))
                    {
                        thisModifiersProp.InsertArrayElementAtIndex(modifiersi);
                    }
                    thisModifiersProp.serializedObject.ApplyModifiedProperties();
                }
            }
            EditorGUI.indentLevel = startingIndent;
            EditorGUI.EndProperty();
        }
        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);
        }
        /// <summary>
        ///  Updates an Existing SlotDataAsset.
        /// </summary>
        /// <param name="slot">The existing SlotDataAsset to be updated</param>
        /// <param name="mesh">Mesh.</param>
        /// <param name="material">Material.</param>
        /// <param name="prefabMesh">Prefab mesh.</param>
        /// <param name="rootBone">Root bone.</param>
        public static void UpdateSlotData(SlotDataAsset slot, SkinnedMeshRenderer mesh, UMAMaterial material, SkinnedMeshRenderer prefabMesh, string rootBone)
        {
            string path      = UMAUtils.GetAssetFolder(AssetDatabase.GetAssetPath(slot));
            string assetName = slot.slotName;

            if (path.Length <= 0)
            {
                Debug.LogWarning("CreateSlotData: Path to existing asset is empty!");
                return;
            }

            GameObject          tempGameObject         = UnityEngine.Object.Instantiate(mesh.transform.parent.gameObject) as GameObject;
            var                 resultingSkinnedMeshes = tempGameObject.GetComponentsInChildren <SkinnedMeshRenderer>();
            SkinnedMeshRenderer resultingSkinnedMesh   = null;

            foreach (var skinnedMesh in resultingSkinnedMeshes)
            {
                if (skinnedMesh.name == mesh.name)
                {
                    resultingSkinnedMesh = skinnedMesh;
                }
            }

            Mesh resultingMesh;

            if (prefabMesh != null)
            {
                resultingMesh = SeamRemoval.PerformSeamRemoval(resultingSkinnedMesh, prefabMesh, 0.0001f);
                resultingSkinnedMesh.sharedMesh = resultingMesh;
                SkinnedMeshAligner.AlignBindPose(prefabMesh, resultingSkinnedMesh);
            }
            else
            {
                resultingMesh = (Mesh)GameObject.Instantiate(resultingSkinnedMesh.sharedMesh);
            }

            var usedBonesDictionary = CompileUsedBonesDictionary(resultingMesh);

            if (usedBonesDictionary.Count != resultingSkinnedMesh.bones.Length)
            {
                resultingMesh = BuildNewReduceBonesMesh(resultingMesh, usedBonesDictionary);
            }

            AssetDatabase.CreateAsset(resultingMesh, path + '/' + mesh.name + ".asset");

            tempGameObject.name = mesh.transform.parent.gameObject.name;
            Transform[] transformList = tempGameObject.GetComponentsInChildren <Transform>();

            GameObject newObject = new GameObject();

            for (int i = 0; i < transformList.Length; i++)
            {
                if (transformList[i].name == rootBone)
                {
                    transformList[i].parent = newObject.transform;
                }
                else if (transformList[i].name == mesh.name)
                {
                    transformList[i].parent = newObject.transform;
                }
            }

            GameObject.DestroyImmediate(tempGameObject);
            resultingSkinnedMesh = newObject.GetComponentInChildren <SkinnedMeshRenderer>();
            if (resultingSkinnedMesh)
            {
                if (usedBonesDictionary.Count != resultingSkinnedMesh.bones.Length)
                {
                    resultingSkinnedMesh.bones = BuildNewReducedBonesList(resultingSkinnedMesh.bones, usedBonesDictionary);
                }
                resultingSkinnedMesh.sharedMesh = resultingMesh;
            }
#if UNITY_2018_3_OR_NEWER
            var skinnedResult = PrefabUtility.SaveAsPrefabAsset(newObject, path + '/' + assetName + "_Skinned.prefab");
#else
            var skinnedResult = UnityEditor.PrefabUtility.CreatePrefab(path + '/' + assetName + "_Skinned.prefab", newObject);
#endif
            GameObject.DestroyImmediate(newObject);

            var meshgo            = skinnedResult.transform.Find(mesh.name);
            var finalMeshRenderer = meshgo.GetComponent <SkinnedMeshRenderer>();

            slot.UpdateMeshData(finalMeshRenderer, rootBone);
            var cloth = mesh.GetComponent <Cloth>();
            if (cloth != null)
            {
                slot.meshData.RetrieveDataFromUnityCloth(cloth);
            }
            AssetDatabase.SaveAssets();
        }
        //The legacy method for applying skeletonModifiers defined inside this converter
        private void ApplySkeletonModifiers(UMAData umaData, UMADnaBase umaDna, UMASkeleton skeleton)
        {
            for (int i = 0; i < _skeletonModifiers.Count; i++)
            {
                _skeletonModifiers[i].umaDNA = umaDna;
                //getting rid of BoneHashes list - when a bone name is added in the editor the skeleton modifier always generates the hash

                var thisHash = (_skeletonModifiers[i].hash != 0) ? _skeletonModifiers[i].hash : UMAUtils.StringToHash(_skeletonModifiers[i].hashName);

                //These are a Vector3 where Value?.x is the calculated value and Value?.y is min and Value?.z is max
                var thisValueX = _skeletonModifiers[i].CalculateValueX(umaDna);
                var thisValueY = _skeletonModifiers[i].CalculateValueY(umaDna);
                var thisValueZ = _skeletonModifiers[i].CalculateValueZ(umaDna);

                //use the overallScaleBoneHash property instead so the user can define the bone that is used here (by default its the 'Position' bone in an UMA Rig)

                /*if (_skeletonModifiers[i].hash == overallScaleBoneHash && _skeletonModifiers[i].property == SkeletonModifier.SkeletonPropType.Scale)
                 * {
                 *      var calcVal = thisValueX.x - _skeletonModifiers[i].valuesX.val.value + overallScale;//effectively (when dna is 0)1-1+0.88
                 *      Debug.Log("DCSUMA overallScale calcVal[" + calcVal + "] =  (thisValueX.x [" + thisValueX.x + "] - _skeletonModifiers[i].valuesX.val.value[" + _skeletonModifiers[i].valuesX.val.value + "] + overallScale[" + overallScale+"]");
                 *      var overallScaleCalc = Mathf.Clamp(calcVal, thisValueX.y, thisValueX.z);
                 *      skeleton.SetScale(_skeletonModifiers[i].hash, new Vector3(overallScaleCalc, overallScaleCalc, overallScaleCalc));
                 * }
                 * else*/if (_skeletonModifiers[i].property == SkeletonModifier.SkeletonPropType.Position)
                {
                    skeleton.SetPositionRelative(thisHash,
                                                 new Vector3(
                                                     Mathf.Clamp(thisValueX.x, thisValueX.y, thisValueX.z),
                                                     Mathf.Clamp(thisValueY.x, thisValueY.y, thisValueY.z),
                                                     Mathf.Clamp(thisValueZ.x, thisValueZ.y, thisValueZ.z)));
                }
                else if (_skeletonModifiers[i].property == SkeletonModifier.SkeletonPropType.Rotation)
                {
                    skeleton.SetRotationRelative(thisHash,
                                                 Quaternion.Euler(new Vector3(
                                                                      Mathf.Clamp(thisValueX.x, thisValueX.y, thisValueX.z),
                                                                      Mathf.Clamp(thisValueY.x, thisValueY.y, thisValueY.z),
                                                                      Mathf.Clamp(thisValueZ.x, thisValueZ.y, thisValueZ.z))), 1f);
                }
                else if (_skeletonModifiers[i].property == SkeletonModifier.SkeletonPropType.Scale)
                {
                    skeleton.SetScale(thisHash,
                                      new Vector3(
                                          Mathf.Clamp(thisValueX.x, thisValueX.y, thisValueX.z),
                                          Mathf.Clamp(thisValueY.x, thisValueY.y, thisValueY.z),
                                          Mathf.Clamp(thisValueZ.x, thisValueZ.y, thisValueZ.z)));
                }
            }
        }
        public static SlotDataAsset CreateSlotData(string slotFolder, string assetFolder, string assetName, SkinnedMeshRenderer mesh, UMAMaterial material, SkinnedMeshRenderer prefabMesh, string rootBone, bool binarySerialization = false)
        {
            if (!System.IO.Directory.Exists(slotFolder + '/' + assetFolder))
            {
                System.IO.Directory.CreateDirectory(slotFolder + '/' + assetFolder);
            }

            if (!System.IO.Directory.Exists(slotFolder + '/' + assetName))
            {
                System.IO.Directory.CreateDirectory(slotFolder + '/' + assetName);
            }

            GameObject tempGameObject = UnityEngine.Object.Instantiate(mesh.transform.parent.gameObject) as GameObject;

            var resultingSkinnedMeshes = tempGameObject.GetComponentsInChildren <SkinnedMeshRenderer>();
            SkinnedMeshRenderer resultingSkinnedMesh = null;

            foreach (var skinnedMesh in resultingSkinnedMeshes)
            {
                if (skinnedMesh.name == mesh.name)
                {
                    resultingSkinnedMesh = skinnedMesh;
                }
            }

            Mesh resultingMesh;

            if (prefabMesh != null)
            {
                resultingMesh = SeamRemoval.PerformSeamRemoval(resultingSkinnedMesh, prefabMesh, 0.0001f);
                resultingSkinnedMesh.sharedMesh = resultingMesh;
                SkinnedMeshAligner.AlignBindPose(prefabMesh, resultingSkinnedMesh);
            }
            else
            {
                resultingMesh = (Mesh)GameObject.Instantiate(resultingSkinnedMesh.sharedMesh);
            }

            var usedBonesDictionary = CompileUsedBonesDictionary(resultingMesh);

            if (usedBonesDictionary.Count != resultingSkinnedMesh.bones.Length)
            {
                resultingMesh = BuildNewReduceBonesMesh(resultingMesh, usedBonesDictionary);
            }

            if (binarySerialization)
            {
                //Work around for mesh being serialized as project format settings (text) when binary is much faster.
                //If Unity introduces a way to set mesh as binary serialization then this becomes unnecessary.
                BinaryAssetWrapper binaryAsset = ScriptableObject.CreateInstance <BinaryAssetWrapper>();
                AssetDatabase.CreateAsset(binaryAsset, slotFolder + '/' + assetName + '/' + mesh.name + ".asset");
                AssetDatabase.AddObjectToAsset(resultingMesh, binaryAsset);
            }
            else
            {
                AssetDatabase.CreateAsset(resultingMesh, slotFolder + '/' + assetName + '/' + mesh.name + ".asset");
            }

            tempGameObject.name = mesh.transform.parent.gameObject.name;
            Transform[] transformList = tempGameObject.GetComponentsInChildren <Transform>();

            GameObject newObject = new GameObject();

            for (int i = 0; i < transformList.Length; i++)
            {
                if (transformList[i].name == rootBone)
                {
                    transformList[i].parent = newObject.transform;
                }
                else if (transformList[i].name == mesh.name)
                {
                    transformList[i].parent = newObject.transform;
                }
            }

            GameObject.DestroyImmediate(tempGameObject);
            resultingSkinnedMesh = newObject.GetComponentInChildren <SkinnedMeshRenderer>();
            if (resultingSkinnedMesh)
            {
                if (usedBonesDictionary.Count != resultingSkinnedMesh.bones.Length)
                {
                    resultingSkinnedMesh.bones = BuildNewReducedBonesList(resultingSkinnedMesh.bones, usedBonesDictionary);
                }
                resultingSkinnedMesh.sharedMesh = resultingMesh;
            }

#if UNITY_2018_3_OR_NEWER
            var skinnedResult = PrefabUtility.SaveAsPrefabAsset(newObject, slotFolder + '/' + assetName + '/' + assetName + "_Skinned.prefab");
#else
            var skinnedResult = UnityEditor.PrefabUtility.CreatePrefab(slotFolder + '/' + assetName + '/' + assetName + "_Skinned.prefab", newObject);
#endif
            GameObject.DestroyImmediate(newObject);

            var meshgo            = skinnedResult.transform.Find(mesh.name);
            var finalMeshRenderer = meshgo.GetComponent <SkinnedMeshRenderer>();

            var slot = ScriptableObject.CreateInstance <SlotDataAsset>();
            slot.slotName = assetName;
            //Make sure slots get created with a name hash
            slot.nameHash = UMAUtils.StringToHash(slot.slotName);
            slot.material = material;
            slot.UpdateMeshData(finalMeshRenderer, rootBone);
            var cloth = mesh.GetComponent <Cloth>();
            if (cloth != null)
            {
                slot.meshData.RetrieveDataFromUnityCloth(cloth);
            }
            AssetDatabase.CreateAsset(slot, slotFolder + '/' + assetName + '/' + assetName + "_Slot.asset");
            for (int i = 1; i < slot.meshData.subMeshCount; i++)
            {
                var additionalSlot = ScriptableObject.CreateInstance <SlotDataAsset>();
                additionalSlot.slotName = string.Format("{0}_{1}", assetName, i);
                additionalSlot.material = material;
                additionalSlot.UpdateMeshData(finalMeshRenderer, rootBone);
                additionalSlot.subMeshIndex = i;
                AssetDatabase.CreateAsset(additionalSlot, slotFolder + '/' + assetName + '/' + assetName + "_" + i + "_Slot.asset");
            }
            AssetDatabase.SaveAssets();
            return(slot);
        }
예제 #12
0
 public virtual int GetTypeNameHash()
 {
     return(UMAUtils.StringToHash(GetType().Name));
 }
예제 #13
0
 private void RecursivelyRemoveChildBones(Transform transform)
 {
     GetComponentInChildren <DynamicCharacterAvatar>().umaData.skeleton.RemoveBone(UMAUtils.StringToHash(transform.name));
     foreach (Transform t in transform)
     {
         Debug.Log("RecursivelyRemoveChildBones(" + t + ".");
         RecursivelyRemoveChildBones(t);
     }
 }
예제 #14
0
        private void CreateBonePoseCallback(UMAData umaData)
        {
            UMA.PoseTools.UMABonePose bonePose = CreatePoseAsset("", bonePoseSaveName);
            //I dont think this should have ever overwritten the existing one

            /*if (selectedConverter.startingPose == null)
             * {
             *      bonePose = CreatePoseAsset("", bonePoseSaveName);
             * }
             * else
             * {
             *      bonePose = selectedConverter.startingPose;
             *      bonePose.poses = new UMABonePose.PoseBone[1];
             * }*/

            UMASkeleton skeletonPreDNA  = tempAvatarPreDNA.GetComponent <UMADynamicAvatar>().umaData.skeleton;
            UMASkeleton skeletonPostDNA = tempAvatarPostDNA.GetComponent <UMADynamicAvatar>().umaData.skeleton;

            Transform transformPreDNA;
            Transform transformPostDNA;
            bool      transformDirty;
            int       parentHash;

            foreach (int boneHash in skeletonPreDNA.BoneHashes)
            {
                skeletonPreDNA.TryGetBoneTransform(boneHash, out transformPreDNA, out transformDirty, out parentHash);
                skeletonPostDNA.TryGetBoneTransform(boneHash, out transformPostDNA, out transformDirty, out parentHash);

                if ((transformPreDNA == null) || (transformPostDNA == null))
                {
                    Debug.LogWarning("Bad bone hash in skeleton: " + boneHash);
                    continue;
                }

                if (!LocalTransformsMatch(transformPreDNA, transformPostDNA))
                {
                    bonePose.AddBone(transformPreDNA, transformPostDNA.localPosition, transformPostDNA.localRotation, transformPostDNA.localScale);
                }
            }

            UMAUtils.DestroySceneObject(tempAvatarPreDNA);
            UMAUtils.DestroySceneObject(tempAvatarPostDNA);


            // This can be very helpful for testing

            /*
             * bonePose.ApplyPose(skeletonPreDNA, 1.0f);
             */

            EditorUtility.SetDirty(bonePose);
            AssetDatabase.SaveAssets();

            if (_applyAndResetOnCreateBP)
            {
                DynamicDNAConverterController converterController = (selectedConverter is DynamicDNAConverterController) ? (selectedConverter as DynamicDNAConverterController) : null;
                DynamicDNAConverterBehaviour  converterBehaviour  = (selectedConverter is DynamicDNAConverterBehaviour) ? (selectedConverter as DynamicDNAConverterBehaviour) : null;
                //UMA2.8+ fixDNAPrefabs Removed the converterBehaviour.ConverterController field, it should be directly assigned to the Races/Slots now
                //if (converterBehaviour.ConverterController != null)
                //	converterController = converterBehaviour.ConverterController;
                if (converterController != null)
                {
                    //find the first BonePoseDNAConverterPlugin and add the pose to it
                    var existingBPCPs = converterController.GetPlugins(typeof(BonePoseDNAConverterPlugin));
                    BonePoseDNAConverterPlugin thisBPCP;
                    if (existingBPCPs.Count > 0)
                    {
                        thisBPCP = existingBPCPs[0] as BonePoseDNAConverterPlugin;
                        //Turn off any other starting poses?
                        for (int i = 0; i < existingBPCPs.Count; i++)
                        {
                            for (int bi = 0; bi < (existingBPCPs[i] as BonePoseDNAConverterPlugin).poseDNAConverters.Count; bi++)
                            {
                                (existingBPCPs[i] as BonePoseDNAConverterPlugin).poseDNAConverters[bi].startingPoseWeight = 0f;
                            }
                        }
                    }
                    else
                    {
                        //if there isn't one create it
                        thisBPCP = converterController.AddPlugin(typeof(BonePoseDNAConverterPlugin)) as BonePoseDNAConverterPlugin;
                    }
                    thisBPCP.poseDNAConverters.Add(new BonePoseDNAConverterPlugin.BonePoseDNAConverter(bonePose, 1f));
                    Debug.Log(bonePose.name + " added as a starting pose to " + thisBPCP.name);
                }
                else if (converterBehaviour != null)
                {
                    // Set this asset as the converters pose asset
                    converterBehaviour.startingPose = bonePose;
                    //make sure its fully applied
                    converterBehaviour.startingPoseWeight = 1f;
                }

                // Reset all the DNA values for target Avatar to default
                UMADnaBase[] targetDNA = activeUMA.umaData.GetAllDna();
                foreach (UMADnaBase dnaEntry in targetDNA)
                {
                    for (int i = 0; i < dnaEntry.Values.Length; i++)
                    {
                        dnaEntry.SetValue(i, 0.5f);
                    }
                }

                // Optionally clear the DNA from the base recipe,
                // since it's now included in the new starting pose
                UMARecipeBase baseRaceRecipe = activeUMA.umaData.umaRecipe.GetRace().baseRaceRecipe;
                if (baseRaceRecipe != null)
                {
                    if (EditorUtility.DisplayDialog("Base Recipe Cleanup", "Starting Pose created. Remove DNA from base recipe of active race? Choose 'RemoveDNA' if your intention is to replace modifications made by a recipes starting DNA values with the created pose.", "Remove DNA", "Keep DNA"))
                    {
                        UMAData.UMARecipe baseRecipeData = new UMAData.UMARecipe();
                        baseRaceRecipe.Load(baseRecipeData, activeUMA.context);
                        baseRecipeData.ClearDna();
                        baseRaceRecipe.Save(baseRecipeData, activeUMA.context);
                    }
                }
            }
        }
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            if (!Init(hashNames, hashes))
            {
                return;
            }

            int startingIndent = EditorGUI.indentLevel;

            EditorGUI.BeginProperty(position, label, property);

            string thisHashName = property.FindPropertyRelative("_hashName").stringValue;

            var currRect = new Rect(position.xMin, position.yMin, position.width, EditorGUIUtility.singleLineHeight);

            string betterLabel = label.text;

            if (property.FindPropertyRelative("_property").enumDisplayNames[property.FindPropertyRelative("_property").enumValueIndex] != "")
            {
                betterLabel += " (" + property.FindPropertyRelative("_property").enumDisplayNames[property.FindPropertyRelative("_property").enumValueIndex] + ")";
            }

            List <string> boneNames = new List <string>();

            if (bonesInSkeleton != null)
            {
                boneNames = new List <string>(bonesInSkeleton);
            }
            else
            {
                boneNames = new List <string>(hashNames);
            }

            int hashNameIndex = boneNames.IndexOf(thisHashName);

            //Warn about current Bone not being available in active Avatar if we are in playMode (i.e. got sent BonesInSkeleton)
            if (hashNameIndex == -1 && bonesInSkeleton != null)
            {
                boneNames.Insert(0, thisHashName + " (missing)");
                hashNameIndex = 0;
                var warningRect    = new Rect((currRect.xMin), currRect.yMin, 20f, currRect.height);
                var warningIconGUI = new GUIContent("", thisHashName + " was not a bone in the Avatars Skeleton. Please choose another bone for this modifier or delete it.");
                warningIconGUI.image = warningIcon;
                betterLabel         += " (missing)";
                GUI.Label(warningRect, warningIconGUI, warningStyle);
            }
            //Draw the foldout- toolbar-ish style here?
            property.isExpanded = EditorGUI.Foldout(currRect, property.isExpanded, betterLabel, true);
            if (property.isExpanded)
            {
                EditorGUI.indentLevel++;

                //THE BONE NAME FIELD
                currRect = new Rect(currRect.xMin, currRect.yMax + padding, currRect.width, EditorGUIUtility.singleLineHeight);
                if (boneNames.Count > 0)
                {
                    int newHashNameIndex = hashNameIndex;
                    EditorGUI.BeginChangeCheck();
                    newHashNameIndex = EditorGUI.Popup(currRect, "Bone Name", hashNameIndex, boneNames.ToArray());
                    if (EditorGUI.EndChangeCheck())
                    {
                        if (newHashNameIndex != hashNameIndex)
                        {
                            property.FindPropertyRelative("_hashName").stringValue = boneNames[newHashNameIndex];
                            property.FindPropertyRelative("_hash").intValue        = UMAUtils.StringToHash(boneNames[newHashNameIndex]);
                            property.serializedObject.ApplyModifiedProperties();
                        }
                    }
                }
                else
                {
                    //make sure the hash is changed if the name is edited
                    EditorGUI.BeginChangeCheck();
                    EditorGUI.PropertyField(currRect, property.FindPropertyRelative("_hashName"), new GUIContent("Bone Name"));
                    if (EditorGUI.EndChangeCheck())
                    {
                        property.FindPropertyRelative("_hash").intValue = UMAUtils.StringToHash(property.FindPropertyRelative("_hashName").stringValue);
                    }
                }

                //THE PROPERTY FIELD
                currRect = new Rect(currRect.xMin, currRect.yMax + padding, currRect.width, EditorGUIUtility.singleLineHeight);
                EditorGUI.PropertyField(currRect, property.FindPropertyRelative("_property"));


                //X/Y/Z VALUES TABS

                SerializedProperty subValsToOpen = null;
                var valuesX = property.FindPropertyRelative("_valuesX");
                var valuesY = property.FindPropertyRelative("_valuesY");
                var valuesZ = property.FindPropertyRelative("_valuesZ");

                tabsArea = currRect = new Rect(currRect.xMin + (EditorGUI.indentLevel * 10f), currRect.yMax + padding, currRect.width - (EditorGUI.indentLevel * 10f), EditorGUIUtility.singleLineHeight);

                //activeTab = valuesX.isExpanded ? 0 : (valuesY.isExpanded ? 1 : (valuesZ.isExpanded ? 2 : 0));
                //subValsToOpen = valuesX.isExpanded ? valuesX : (valuesY.isExpanded ? valuesY : (valuesZ.isExpanded ? valuesZ : valuesX));
                activeTab               = 0;
                subValsToOpen           = valuesX;
                valueLabel.text         = "X Value";
                valueOverrideLabel.text = "Intitial X Value Override";
                if (!valuesX.isExpanded)
                {
                    if (valuesY.isExpanded)
                    {
                        activeTab               = 1;
                        subValsToOpen           = valuesY;
                        valueLabel.text         = "Y Value";
                        valueOverrideLabel.text = "Intitial Y Value Override";
                    }
                    else if (valuesZ.isExpanded)
                    {
                        activeTab               = 2;
                        subValsToOpen           = valuesZ;
                        valueLabel.text         = "Z Value";
                        valueOverrideLabel.text = "Intitial Z Value Override";
                    }
                    else
                    {
                        valuesX.isExpanded = true;
                    }
                }

                EditorGUI.BeginChangeCheck();
                activeTab = GUI.Toolbar(tabsArea, activeTab, tabsLabels, EditorStyles.toolbarButton);
                if (EditorGUI.EndChangeCheck())
                {
                    //make sure any focussed text areas dont prevent the tab from switching
                    GUI.FocusControl(null);
                    if (activeTab == 0)
                    {
                        valuesX.isExpanded      = true;
                        valuesY.isExpanded      = false;
                        valuesZ.isExpanded      = false;
                        valueLabel.text         = "X Value";
                        valueOverrideLabel.text = "Intitial X Value Override";
                    }
                    else if (activeTab == 1)
                    {
                        valuesX.isExpanded      = false;
                        valuesY.isExpanded      = true;
                        valuesZ.isExpanded      = false;
                        subValsToOpen           = valuesY;
                        valueLabel.text         = "Y Value";
                        valueOverrideLabel.text = "Intitial Y Value Override";
                    }
                    else if (activeTab == 2)
                    {
                        valuesX.isExpanded      = false;
                        valuesY.isExpanded      = false;
                        valuesZ.isExpanded      = true;
                        subValsToOpen           = valuesZ;
                        valueLabel.text         = "Z Value";
                        valueOverrideLabel.text = "Intitial Z Value Override";
                    }
                }

                //VALUES TAB CONTENT
                if (subValsToOpen != null)
                {
                    var subValuesVal = subValsToOpen.FindPropertyRelative("_val");
                    var subValuesMin = subValsToOpen.FindPropertyRelative("_min");
                    var subValuesMax = subValsToOpen.FindPropertyRelative("_max");

                    valMinMaxArea = currRect = new Rect(tabsArea.xMin, tabsArea.yMax, tabsArea.width, EditorGUIUtility.singleLineHeight + (padding * 4f));
                    valBox        = new Rect(valMinMaxArea.xMin, valMinMaxArea.yMin + (padding * 2f), valMinMaxArea.width / 3f, valMinMaxArea.height - (padding * 4f));
                    minBox        = new Rect(valBox.xMax, valBox.yMin, valBox.width, valBox.height);
                    maxBox        = new Rect(minBox.xMax, minBox.yMin, minBox.width, minBox.height);
                    valLabel      = new Rect(valBox.xMin + (padding * 6f), valBox.yMin, valLabelWidth, valBox.height);
                    valVal        = new Rect(valLabel.xMax + (padding), valLabel.yMin, (valBox.width - valLabelWidth) - (padding * 10f), valLabel.height);
                    minLabel      = new Rect(minBox.xMin + (padding * 2f), minBox.yMin, minMaxLabelWidth, minBox.height);
                    minVal        = new Rect(minLabel.xMax, minLabel.yMin, (minBox.width - minMaxLabelWidth) - (padding * 4f), minLabel.height);
                    maxLabel      = new Rect(maxBox.xMin + (padding * 2f), maxBox.yMin, minMaxLabelWidth, maxBox.height);
                    maxVal        = new Rect(maxLabel.xMax, maxLabel.yMin, (maxBox.width - minMaxLabelWidth) - (padding * 4f), maxLabel.height);

                    if (subValuesVal.isExpanded)
                    {
                        valMinMaxArea.height += EditorGUIUtility.singleLineHeight + padding;
                    }
                    //VALUE/MIN/MAX FIELDS

                    EditorGUI.DrawRect(valMinMaxArea, new Color32(255, 255, 255, 100));
                    var prevIndent = EditorGUI.indentLevel;
                    EditorGUI.indentLevel = 0;

                    //Value Field

                    //Show another line here if this is expanded that lets the user change the starting value
                    subValuesVal.isExpanded = EditorGUI.Foldout(valLabel, subValuesVal.isExpanded, valueLabel, true);
                    EditorGUI.BeginDisabledGroup(true);
                    subValuesVal.FindPropertyRelative("_value").floatValue = EditorGUI.FloatField(valVal, subValuesVal.FindPropertyRelative("_value").floatValue);
                    EditorGUI.EndDisabledGroup();
                    if (subValuesVal.isExpanded)
                    {
                        var subValuesValRect = new Rect(tabsArea.xMin + (padding * 4f), tabsArea.yMax + (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing * 8), tabsArea.width - (padding * 8f), EditorGUIUtility.singleLineHeight);
                        subValuesVal.FindPropertyRelative("_value").floatValue = EditorGUI.FloatField(subValuesValRect, valueOverrideLabel, subValuesVal.FindPropertyRelative("_value").floatValue);
                    }

                    //Min Field
                    EditorGUI.LabelField(minLabel, "Min");
                    subValuesMin.floatValue = EditorGUI.FloatField(minVal, subValuesMin.floatValue);

                    //Max Field
                    EditorGUI.LabelField(maxLabel, "Max");
                    subValuesMax.floatValue = EditorGUI.FloatField(maxVal, subValuesMax.floatValue);
                    //EditorGUI.indentLevel = prevIndent;

                    //VALUE MODIFIERS AREA

                    var legacyModifiersProp  = subValuesVal.FindPropertyRelative("_modifiers");
                    var legacyModifiersCount = legacyModifiersProp.arraySize;

                    var modifyingDNAProp  = subValuesVal.FindPropertyRelative("_modifyingDNA");
                    var modifyingDNACount = modifyingDNAProp.FindPropertyRelative("_dnaEvaluators").arraySize;

                    currRect      = new Rect(currRect.xMin, valMinMaxArea.yMax + 2f, currRect.width, EditorGUIUtility.singleLineHeight);
                    modifiersArea = new Rect(currRect.xMin, currRect.yMin, currRect.width, ((EditorGUIUtility.singleLineHeight + padding) * (legacyModifiersCount + 2)));                    //plus 2 for label and add button

                    if (modifyingDNACount != 0 || !_allowLegacyDNADrawer)
                    {
                        modifiersArea = new Rect(currRect.xMin, currRect.yMin, currRect.width, (EditorGUI.GetPropertyHeight(modifyingDNAProp) + padding));
                    }

                    EditorGUI.DrawRect(modifiersArea, new Color32(255, 255, 255, 100));

                    //Pad the current Rect
                    currRect.xMin  += padding * 2f;
                    currRect.width -= padding * 2f;

                    //When modifiers get upgraded to _modifyingDNA they get cleared
                    //But for now
                    if (modifyingDNACount == 0 && _allowLegacyDNADrawer)
                    {
                        //EditorGUI.indentLevel++;
                        EditorGUI.LabelField(currRect, "Value Modifiers");
                        //EditorGUI.indentLevel--;

                        //Draw modifiers list
                        for (int i = 0; i < legacyModifiersCount; i++)
                        {
                            currRect       = new Rect(currRect.xMin, currRect.yMax + padding, currRect.width, EditorGUIUtility.singleLineHeight);
                            modifiersProps = new Rect(currRect.xMin, currRect.yMin, currRect.width - delButWidth, EditorGUIUtility.singleLineHeight);
                            modifiersDel   = new Rect(modifiersProps.xMax, currRect.yMin, delButWidth, EditorGUIUtility.singleLineHeight);
                            thisSpValDrawer.OnGUI(modifiersProps, legacyModifiersProp.GetArrayElementAtIndex(i), new GUIContent(""));
                            if (GUI.Button(modifiersDel, "X"))
                            {
                                legacyModifiersProp.DeleteArrayElementAtIndex(i);
                            }
                        }

                        //Draw the add button
                        modifiersAdd = new Rect(currRect.xMax - addButWidth, currRect.yMax + padding, addButWidth, EditorGUIUtility.singleLineHeight);

                        if (GUI.Button(modifiersAdd, "Add"))
                        {
                            legacyModifiersProp.InsertArrayElementAtIndex(legacyModifiersCount);
                        }
                        legacyModifiersProp.serializedObject.ApplyModifiedProperties();
                    }
                    else
                    {
                        var thisModifyingDNARect = new Rect(currRect.xMin, currRect.yMin, currRect.width, position.height - currRect.yMax);
                        EditorGUI.PropertyField(thisModifyingDNARect, modifyingDNAProp);
                    }
                }
            }
            EditorGUI.indentLevel = startingIndent;
            EditorGUI.EndProperty();
        }
예제 #16
0
        protected void UpdateSaccades()
        {
            saccadeDelay -= Time.deltaTime;
            if (saccadeDelay < 0f)
            {
                saccadeTargetPrev = saccadeTarget;

                int   saccadeDirection = Random.Range(0, 4);
                float saccadeOffset    = UMAUtils.GaussianRandom(0f, 0.125f);
                switch (saccadeDirection)
                {
                case 0:
                    saccadeTarget.Set(1f - Mathf.Abs(saccadeOffset), saccadeOffset);
                    break;

                case 1:
                    saccadeTarget.Set(-1f + Mathf.Abs(saccadeOffset), saccadeOffset);
                    break;

                case 2:
                    saccadeTarget.Set(saccadeOffset, 1f - Mathf.Abs(saccadeOffset));
                    break;

                default:
                    saccadeTarget.Set(saccadeOffset, -1f + Mathf.Abs(saccadeOffset));
                    break;
                }

                float saccadeMagnitude = Random.Range(0.01f, 15f);
                float saccadeDistance  = (-6.9f / eyeMovementRange) * Mathf.Log(saccadeMagnitude / 15.7f);
                saccadeDuration = 0.021f + 0.0022f * saccadeDistance * eyeMovementRange;
                saccadeProgress = 0f;

                switch (gazeMode)
                {
                case GazeMode.Listening:
                    if (Mathf.Abs(saccadeDistance) < mutualGazeRange)
                    {
                        saccadeDelay = UMAUtils.GaussianRandom(237.5f / 30f, 47.1f / 30f);
                    }
                    else
                    {
                        saccadeDelay = UMAUtils.GaussianRandom(13f / 30f, 7.1f / 30f);
                    }
                    break;

                default:
                    if (Mathf.Abs(saccadeDistance) < mutualGazeRange)
                    {
                        saccadeDelay = UMAUtils.GaussianRandom(93.9f / 30f, 94.9f / 30f);
                    }
                    else
                    {
                        saccadeDelay = UMAUtils.GaussianRandom(27.8f / 30f, 24f / 30f);
                    }
                    break;
                }

                if (saccadeDelay < MinSaccadeDelay)
                {
                    saccadeDelay = MinSaccadeDelay;
                }

                saccadeTarget *= saccadeDistance;
            }

            if (saccadeProgress < 1f)
            {
                float timeProgress = Time.deltaTime / saccadeDuration;
                float progressRate = 1.5f - 3f * Mathf.Pow(saccadeProgress - 0.5f, 2);
                saccadeProgress += timeProgress * progressRate;

                leftEyeIn_Out   = Mathf.Lerp(saccadeTargetPrev.x, saccadeTarget.x, saccadeProgress);
                leftEyeUp_Down  = Mathf.Lerp(saccadeTargetPrev.y, saccadeTarget.y, saccadeProgress);
                rightEyeIn_Out  = Mathf.Lerp(-saccadeTargetPrev.x, -saccadeTarget.x, saccadeProgress);
                rightEyeUp_Down = Mathf.Lerp(saccadeTargetPrev.y, saccadeTarget.y, saccadeProgress);
            }
            else
            {
                leftEyeIn_Out   = saccadeTarget.x;
                leftEyeUp_Down  = saccadeTarget.y;
                rightEyeIn_Out  = -saccadeTarget.x;
                rightEyeUp_Down = saccadeTarget.y;
            }
        }
예제 #17
0
        public static SlotDataAsset CreateSlotData(string slotFolder, string assetFolder, string assetName, SkinnedMeshRenderer mesh, UMAMaterial material, SkinnedMeshRenderer prefabMesh, string rootBone)
        {
            if (!System.IO.Directory.Exists(slotFolder + '/' + assetFolder))
            {
                System.IO.Directory.CreateDirectory(slotFolder + '/' + assetFolder);
            }

            if (!System.IO.Directory.Exists(slotFolder + '/' + assetName))
            {
                System.IO.Directory.CreateDirectory(slotFolder + '/' + assetName);
            }

            GameObject tempGameObject = UnityEngine.Object.Instantiate(mesh.transform.parent.gameObject) as GameObject;

            PrefabUtility.DisconnectPrefabInstance(tempGameObject);
            var resultingSkinnedMeshes = tempGameObject.GetComponentsInChildren <SkinnedMeshRenderer>();
            SkinnedMeshRenderer resultingSkinnedMesh = null;

            foreach (var skinnedMesh in resultingSkinnedMeshes)
            {
                if (skinnedMesh.name == mesh.name)
                {
                    resultingSkinnedMesh = skinnedMesh;
                }
            }

            Mesh resultingMesh;

            if (prefabMesh != null)
            {
                resultingMesh = SeamRemoval.PerformSeamRemoval(resultingSkinnedMesh, prefabMesh, 0.0001f);
                resultingSkinnedMesh.sharedMesh = resultingMesh;
                SkinnedMeshAligner.AlignBindPose(prefabMesh, resultingSkinnedMesh);
            }
            else
            {
                resultingMesh = (Mesh)GameObject.Instantiate(resultingSkinnedMesh.sharedMesh);
            }

            var usedBonesDictionary = CompileUsedBonesDictionary(resultingMesh);

            if (usedBonesDictionary.Count != resultingSkinnedMesh.bones.Length)
            {
                resultingMesh = BuildNewReduceBonesMesh(resultingMesh, usedBonesDictionary);
            }

            AssetDatabase.CreateAsset(resultingMesh, slotFolder + '/' + assetName + '/' + mesh.name + ".asset");

            tempGameObject.name = mesh.transform.parent.gameObject.name;
            Transform[] transformList = tempGameObject.GetComponentsInChildren <Transform>();

            GameObject newObject = new GameObject();

            for (int i = 0; i < transformList.Length; i++)
            {
                if (transformList[i].name == rootBone)
                {
                    transformList[i].parent = newObject.transform;
                }
                else if (transformList[i].name == mesh.name)
                {
                    transformList[i].parent = newObject.transform;
                }
            }

            GameObject.DestroyImmediate(tempGameObject);
            resultingSkinnedMesh = newObject.GetComponentInChildren <SkinnedMeshRenderer>();
            if (resultingSkinnedMesh)
            {
                if (usedBonesDictionary.Count != resultingSkinnedMesh.bones.Length)
                {
                    resultingSkinnedMesh.bones = BuildNewReducedBonesList(resultingSkinnedMesh.bones, usedBonesDictionary);
                }
                resultingSkinnedMesh.sharedMesh = resultingMesh;
            }

            var skinnedResult = UnityEditor.PrefabUtility.CreatePrefab(slotFolder + '/' + assetName + '/' + assetName + "_Skinned.prefab", newObject);

            GameObject.DestroyImmediate(newObject);

            var meshgo            = skinnedResult.transform.Find(mesh.name);
            var finalMeshRenderer = meshgo.GetComponent <SkinnedMeshRenderer>();

            var slot = ScriptableObject.CreateInstance <SlotDataAsset>();

            slot.slotName = assetName;
            //Make sure slots get created with a name hash
            slot.nameHash = UMAUtils.StringToHash(slot.slotName);
            slot.material = material;
            slot.UpdateMeshData(finalMeshRenderer, rootBone);
            AssetDatabase.CreateAsset(slot, slotFolder + '/' + assetName + '/' + assetName + "_Slot.asset");
            for (int i = 1; i < slot.meshData.subMeshCount; i++)
            {
                var additionalSlot = ScriptableObject.CreateInstance <SlotDataAsset>();
                additionalSlot.slotName = string.Format("{0}_{1}", assetName, i);
                additionalSlot.material = material;
                additionalSlot.UpdateMeshData(finalMeshRenderer, rootBone);
                additionalSlot.subMeshIndex = i;
                AssetDatabase.CreateAsset(additionalSlot, slotFolder + '/' + assetName + '/' + assetName + "_" + i + "_Slot.asset");
            }
            AssetDatabase.SaveAssets();
            return(slot);
        }