// This code is generally the same as used in the DynamicDNAConverterCustomizer // Probably worth breaking it out at some point and having it geenric protected void CreateBonePoseCallback(UMAData umaData) { avatarDNAisDirty = false; UMABonePose bonePose = ScriptableObject.CreateInstance <UMABonePose>(); UMAData umaPreDNA = tempAvatarPreDNA.GetComponent <UMADynamicAvatar>().umaData; UMAData umaPostDNA = tempAvatarPostDNA.GetComponent <UMADynamicAvatar>().umaData; UMADnaBase activeDNA = umaPostDNA.umaRecipe.GetDna(selectedDNAHash); UMASkeleton skeletonPreDNA = umaPreDNA.skeleton; UMASkeleton skeletonPostDNA = umaPostDNA.skeleton; if (poseSaveIndex < 0) { poseSaveName = startingPoseName; // Now that StartingPose has been generated // add the active DNA to the pre DNA avatar DnaConverterBehaviour activeConverter = sourceUMA.umaRecipe.raceData.GetConverter(sourceUMA.umaRecipe.GetDna(selectedDNAHash)); umaPreDNA.umaRecipe.raceData.dnaConverterList = new DnaConverterBehaviour[1]; umaPreDNA.umaRecipe.raceData.dnaConverterList[0] = activeConverter; umaPreDNA.umaRecipe.raceData.UpdateDictionary(); umaPreDNA.umaRecipe.EnsureAllDNAPresent(); umaPreDNA.Dirty(true, false, true); } 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); } } int activeDNACount = activeDNA.Count; for (int i = 0; i < activeDNACount; i++) { activeDNA.SetValue(i, 0.5f); } AssetDatabase.CreateAsset(bonePose, folderPath + "/" + poseSaveName + ".asset"); EditorUtility.SetDirty(bonePose); AssetDatabase.SaveAssets(); poseSaveIndex++; if (poseSaveIndex < activeDNACount) { poseSaveName = activeDNA.Names[poseSaveIndex] + "_0"; activeDNA.SetValue(poseSaveIndex, 0.0f); avatarDNAisDirty = true; } else if (poseSaveIndex < (activeDNACount * 2)) { int dnaIndex = poseSaveIndex - activeDNACount; poseSaveName = activeDNA.Names[dnaIndex] + "_1"; activeDNA.SetValue(dnaIndex, 1.0f); umaPostDNA.Dirty(); avatarDNAisDirty = true; } else { Destroy(tempAvatarPreDNA); Destroy(tempAvatarPostDNA); // Build a prefab DNA Converter and populate it with the morph set string assetName = "Morph Set"; string assetPath = AssetDatabase.GenerateUniqueAssetPath(folderPath + "/" + assetName + ".asset"); MorphSetDnaAsset asset = CustomAssetUtility.CreateAsset <MorphSetDnaAsset>(assetPath, false); SerializedObject serializedAsset = new SerializedObject(asset); SerializedProperty startingPose = serializedAsset.FindProperty("startingPose"); startingPose.objectReferenceValue = AssetDatabase.LoadAssetAtPath <UMABonePose>(folderPath + "/" + startingPoseName + ".asset"); SerializedProperty morphSetArray = serializedAsset.FindProperty("dnaMorphs"); morphSetArray.ClearArray(); for (int i = 0; i < activeDNACount; i++) { string posePairName = activeDNA.Names[i]; morphSetArray.InsertArrayElementAtIndex(i); SerializedProperty posePair = morphSetArray.GetArrayElementAtIndex(i); SerializedProperty dnaEntryName = posePair.FindPropertyRelative("dnaEntryName"); dnaEntryName.stringValue = posePairName; SerializedProperty zeroPose = posePair.FindPropertyRelative("poseZero"); zeroPose.objectReferenceValue = AssetDatabase.LoadAssetAtPath <UMABonePose>(folderPath + "/" + posePairName + "_0.asset"); SerializedProperty onePose = posePair.FindPropertyRelative("poseOne"); onePose.objectReferenceValue = AssetDatabase.LoadAssetAtPath <UMABonePose>(folderPath + "/" + posePairName + "_1.asset"); } serializedAsset.ApplyModifiedPropertiesWithoutUndo(); // Build a prefab DNA Converter and populate it with the morph set string prefabName = "Converter Prefab"; string prefabPath = AssetDatabase.GenerateUniqueAssetPath(folderPath + "/" + prefabName + ".prefab"); GameObject tempConverterPrefab = new GameObject(prefabName); MorphSetDnaConverterBehaviour converter = tempConverterPrefab.AddComponent <MorphSetDnaConverterBehaviour>(); SerializedObject serializedConverter = new SerializedObject(converter); SerializedProperty morphSet = serializedAsset.FindProperty("morphSet"); morphSet.objectReferenceValue = AssetDatabase.LoadAssetAtPath <MorphSetDnaAsset>(assetPath); serializedConverter.ApplyModifiedPropertiesWithoutUndo(); PrefabUtility.CreatePrefab(prefabPath, tempConverterPrefab); DestroyImmediate(tempConverterPrefab, false); } }
protected void SavePoseSet() { DnaConverterBehaviour activeConverter = sourceUMA.umaRecipe.raceData.GetConverter(sourceUMA.umaRecipe.GetDna(selectedDNAHash)); folderPath = AssetDatabase.GetAssetPath(outputFolder) + "/" + activeConverter.name; if (!AssetDatabase.IsValidFolder(folderPath)) { string folderGUID = AssetDatabase.CreateFolder(AssetDatabase.GetAssetPath(outputFolder), activeConverter.name); folderPath = AssetDatabase.GUIDToAssetPath(folderGUID); } poseSaveIndex = -1; // Build a temporary version of the Avatar with no DNA to get original state SlotData[] activeSlots = sourceUMA.umaRecipe.GetAllSlots(); int slotIndex; tempAvatarPreDNA = new GameObject("Temp Raw Avatar"); tempAvatarPreDNA.transform.parent = sourceUMA.transform.parent; tempAvatarPreDNA.transform.localPosition = Vector3.zero; tempAvatarPreDNA.transform.localRotation = sourceUMA.transform.localRotation; UMADynamicAvatar tempAvatar = tempAvatarPreDNA.AddComponent <UMADynamicAvatar>(); tempAvatar.umaGenerator = sourceUMA.umaGenerator; tempAvatar.Initialize(); tempAvatar.umaData.umaRecipe = new UMAData.UMARecipe(); tempAvatar.umaData.umaRecipe.raceData = ScriptableObject.CreateInstance <RaceData>(); tempAvatar.umaData.umaRecipe.raceData.raceName = "Temp Raw Race"; tempAvatar.umaData.umaRecipe.raceData.TPose = sourceUMA.umaRecipe.raceData.TPose; tempAvatar.umaData.umaRecipe.raceData.umaTarget = sourceUMA.umaRecipe.raceData.umaTarget; slotIndex = 0; foreach (SlotData slotEntry in activeSlots) { if ((slotEntry == null) || slotEntry.dontSerialize) { continue; } tempAvatar.umaData.umaRecipe.SetSlot(slotIndex++, slotEntry); } tempAvatar.Show(); tempAvatarPostDNA = new GameObject("Temp DNA Avatar"); tempAvatarPostDNA.transform.parent = sourceUMA.transform.parent; tempAvatarPostDNA.transform.localPosition = Vector3.zero; tempAvatarPostDNA.transform.localRotation = sourceUMA.transform.localRotation; UMADynamicAvatar tempAvatar2 = tempAvatarPostDNA.AddComponent <UMADynamicAvatar>(); tempAvatar2.umaGenerator = sourceUMA.umaGenerator; tempAvatar2.Initialize(); tempAvatar2.umaData.umaRecipe = new UMAData.UMARecipe(); tempAvatar2.umaData.umaRecipe.raceData = ScriptableObject.CreateInstance <RaceData>(); tempAvatar2.umaData.umaRecipe.raceData.raceName = "Temp DNA Race"; tempAvatar2.umaData.umaRecipe.raceData.TPose = sourceUMA.umaRecipe.raceData.TPose; tempAvatar2.umaData.umaRecipe.raceData.umaTarget = sourceUMA.umaRecipe.raceData.umaTarget; tempAvatar2.umaData.umaRecipe.raceData.dnaConverterList = new DnaConverterBehaviour[1]; tempAvatar2.umaData.umaRecipe.raceData.dnaConverterList[0] = activeConverter; tempAvatar2.umaData.umaRecipe.raceData.UpdateDictionary(); slotIndex = 0; foreach (SlotData slotEntry in activeSlots) { if ((slotEntry == null) || slotEntry.dontSerialize) { continue; } tempAvatar2.umaData.umaRecipe.SetSlot(slotIndex++, slotEntry); } tempAvatar2.umaData.OnCharacterUpdated += CreateBonePoseCallback; tempAvatar2.Show(); }
public override void OnInspectorGUI() { bool dirty = false; DnaConverterBehaviour newSource = EditorGUILayout.ObjectField("DNA Converter", dnaRange.dnaConverter, typeof(DnaConverterBehaviour), true) as DnaConverterBehaviour; if (newSource != dnaRange.dnaConverter) { dnaRange.dnaConverter = newSource; dnaSource = null; if (dnaRange.dnaConverter != null) { dnaSource = dnaRange.dnaConverter.DNAType.GetConstructor(System.Type.EmptyTypes).Invoke(null) as UMADnaBase; } if (dnaSource == null) { entryCount = 0; } else { if (dnaRange.dnaConverter.DNAType == typeof(DynamicUMADna)) { entryCount = ((DynamicDNAConverterBehaviourBase)dnaRange.dnaConverter).dnaAsset.Names.Length; } else { entryCount = dnaSource.Count; } } dnaRange.means = new float[entryCount]; dnaRange.deviations = new float[entryCount]; dnaRange.spreads = new float[entryCount]; for (int i = 0; i < entryCount; i++) { dnaRange.means[i] = 0.5f; dnaRange.deviations[i] = 0.16f; dnaRange.spreads[i] = 0.5f; } dirty = true; } GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1)); if (dnaRange.dnaConverter != null) { GUILayout.Space(2f); GUIStyle headerStyle = new GUIStyle(); headerStyle.alignment = TextAnchor.MiddleCenter; headerStyle.normal.textColor = Color.white; headerStyle.fontSize = 12; EditorGUILayout.LabelField(dnaRange.dnaConverter.DNAType.Name, headerStyle); string[] dnaNames; if (dnaRange.dnaConverter.DNAType == typeof(DynamicUMADna)) { dnaNames = ((DynamicDNAConverterBehaviourBase)dnaRange.dnaConverter).dnaAsset.Names; } else { dnaNames = dnaSource.Names; } for (int i = 0; i < entryCount; i++) { float currentMin = dnaRange.means[i] - dnaRange.spreads[i]; float currentMax = dnaRange.means[i] + dnaRange.spreads[i]; float min = currentMin; float max = currentMax; EditorGUILayout.PrefixLabel(dnaNames[i]); EditorGUILayout.MinMaxSlider(ref min, ref max, 0f, 1f); if ((min != currentMin) || (max != currentMax)) { dnaRange.means[i] = (min + max) / 2f; dnaRange.spreads[i] = (max - min) / 2f; dnaRange.deviations[i] = dnaRange.spreads[i] / 3f; dirty = true; } } } if (dirty) { EditorUtility.SetDirty(dnaRange); AssetDatabase.SaveAssets(); } }