/// <summary> /// Load a UMA recipe and additional recipes into the avatar. /// </summary> /// <param name="umaRecipe">UMA recipe.</param> /// <param name="umaAdditionalRecipes">Additional recipes.</param> public virtual void Load(UMARecipeBase umaRecipe, params UMARecipeBase[] umaAdditionalRecipes) { if (umaRecipe == null) { return; } if (umaData == null) { Initialize(); } Profiler.BeginSample("Load"); this.umaRecipe = umaRecipe; umaRecipe.Load(umaData.umaRecipe, context); umaData.AddAdditionalRecipes(umaAdditionalRecipes, context); if (umaRace != umaData.umaRecipe.raceData) { UpdateNewRace(); } else { UpdateSameRace(); } Profiler.EndSample(); }
public void Initialize( UMAContext context, UMAGeneratorBase generator, UMAData data, [InjectOptional] UMARecipeBase recipe, [InjectOptional] UMARecipeBase [] additionalRecipe, ThirdPersonCharacter controller) { base.context = context; base.umaGenerator = generator; base.umaData = data; base.umaRecipe = recipe; base.umaAdditionalRecipes = additionalRecipe; this.controller = controller; this.gameObject.transform.SetParent(controller.gameObject.transform); this.gameObject.transform.localPosition = Vector3.zero; this.gameObject.transform.localRotation = Quaternion.identity; base.Initialize(); if (umaAdditionalRecipes == null || umaAdditionalRecipes.Length == 0) { Load(umaRecipe); } else { Load(umaRecipe, umaAdditionalRecipes); } }
public virtual GameObject CreateAvatar(UMARecipeBase recipe) { var GO = new GameObject(recipe.name); var avatar = GO.AddComponent<UMADynamicAvatar>(); avatar.umaRecipe = recipe; avatar.loadOnStart = true; return GO; }
public static void Hide(UMARecipeBase recipeBase) { var avatar = GetPreview(recipeBase).GetComponent<UMADynamicAvatar>(); var persistance = GetPowerPackPersistanceType(); var hideAvatarMethod = persistance.GetMethod("HideAvatar", new Type[] { typeof(UMAAvatarBase) }); var instance = GetPowerPackPersistanceInstance(); hideAvatarMethod.Invoke(instance, new object[] { avatar }); ReleasePowerPackPersistanceInstance(instance); }
public virtual GameObject CreateAvatar(UMARecipeBase recipe) { var GO = new GameObject(recipe.name); var avatar = GO.AddComponent <UMADynamicAvatar>(); avatar.umaRecipe = recipe; avatar.loadOnStart = true; return(GO); }
public static void Hide(UMARecipeBase recipeBase) { var avatar = GetPreview(recipeBase).GetComponent <UMADynamicAvatar>(); var persistance = GetPowerPackPersistanceType(); var hideAvatarMethod = persistance.GetMethod("HideAvatar", new Type[] { typeof(UMAAvatarBase) }); var instance = GetPowerPackPersistanceInstance(); hideAvatarMethod.Invoke(instance, new object[] { avatar }); ReleasePowerPackPersistanceInstance(instance); }
public static void Refresh(UMARecipeBase recipeBase) { var avatar = GetPreview(recipeBase).GetComponent<UMADynamicAvatar>(); var persistance = GetPowerPackPersistanceType(); SetAvatarDestroyParent(avatar, false); var hideAvatarMethod = persistance.GetMethod("HideAvatar", new Type[] { typeof(UMAAvatarBase) }); var instance = GetPowerPackPersistanceInstance(); hideAvatarMethod.Invoke(instance, new object[] { avatar }); var showAvatarMethod = persistance.GetMethod("ShowAvatar", new Type[] { typeof(UMAAvatarBase) }); showAvatarMethod.Invoke(instance, new object[] { avatar }); SetAvatarDestroyParent(avatar, true); ReleasePowerPackPersistanceInstance(instance); }
public void Load(UMARecipeBase umaRecipe) { Profiler.BeginSample("Load"); var oldRace = umaData.umaRecipe.raceData; this.umaRecipe = umaRecipe; umaRecipe.Load(umaData, context); if (oldRace != umaData.umaRecipe.raceData) { UpdateNewRace(); } else { UpdateSameRace(); } Profiler.EndSample(); }
public void Load(UMARecipeBase umaRecipe) { if (umaRecipe == null) return; Profiler.BeginSample("Load"); this.umaRecipe = umaRecipe; umaRecipe.Load(umaData.umaRecipe, context); if (umaRace != umaData.umaRecipe.raceData) { UpdateNewRace(); } else { UpdateSameRace(); } Profiler.EndSample(); }
public static void Refresh(UMARecipeBase recipeBase) { var avatar = GetPreview(recipeBase).GetComponent <UMADynamicAvatar>(); var persistance = GetPowerPackPersistanceType(); SetAvatarDestroyParent(avatar, false); var hideAvatarMethod = persistance.GetMethod("HideAvatar", new Type[] { typeof(UMAAvatarBase) }); var instance = GetPowerPackPersistanceInstance(); hideAvatarMethod.Invoke(instance, new object[] { avatar }); var showAvatarMethod = persistance.GetMethod("ShowAvatar", new Type[] { typeof(UMAAvatarBase) }); showAvatarMethod.Invoke(instance, new object[] { avatar }); SetAvatarDestroyParent(avatar, true); ReleasePowerPackPersistanceInstance(instance); }
public static void Show(UMARecipeBase recipeBase) { var go = new GameObject("PowerTools_" + recipeBase.name); go.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector; var avatar = go.AddComponent<UMADynamicAvatar>(); avatar.umaRecipe = recipeBase; var persistance = GetPowerPackPersistanceType(); var showAvatarMethod = persistance.GetMethod("ShowAvatar", new Type[] { typeof(UMAAvatarBase) }); var instance = GetPowerPackPersistanceInstance(); showAvatarMethod.Invoke(instance, new object[] { avatar }); ReleasePowerPackPersistanceInstance(instance); SetAvatarDestroyParent(avatar, true); #if UNITY_EDITOR go.transform.position = UnityEditor.SceneView.lastActiveSceneView.pivot - new Vector3(0,1,0); #endif }
bool ShouldLoad(eLoaded itemsToLoad, AssetItem ai) { switch (itemsToLoad) { case eLoaded.Resx: return(ai.IsResource || (ai.IsAddressable == false)); case eLoaded.Keep: return(ai.IsAlwaysLoaded); case eLoaded.Addressable: return(ai.IsAddressable); case eLoaded.NonAddressable: return(!ai.IsAddressable); case eLoaded.NoGroups: { if (ai.Item is UMARecipeBase) { UMARecipeBase ubr = ai.Item as UMARecipeBase; if (!LoadedLabels.Contains(ubr.AssignedLabel)) { return(true); } } return(false); } case eLoaded.SelectedOnly: { if (LoadOnly.Contains(ai)) { return(true); } else { return(false); } } } return(true); }
public virtual void Load(UMARecipeBase umaRecipe) { if (umaRecipe == null) { return; } Profiler.BeginSample("Load"); this.umaRecipe = umaRecipe; umaRecipe.Load(umaData.umaRecipe, context); if (umaRace != umaData.umaRecipe.raceData) { UpdateNewRace(); } else { UpdateSameRace(); } Profiler.EndSample(); }
public static void Show(UMARecipeBase recipeBase) { var go = new GameObject("PowerTools_" + recipeBase.name); go.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector; var avatar = go.AddComponent <UMADynamicAvatar>(); avatar.umaRecipe = recipeBase; var persistance = GetPowerPackPersistanceType(); var showAvatarMethod = persistance.GetMethod("ShowAvatar", new Type[] { typeof(UMAAvatarBase) }); var instance = GetPowerPackPersistanceInstance(); showAvatarMethod.Invoke(instance, new object[] { avatar }); ReleasePowerPackPersistanceInstance(instance); SetAvatarDestroyParent(avatar, true); #if UNITY_EDITOR go.transform.position = UnityEditor.SceneView.lastActiveSceneView.pivot - new Vector3(0, 1, 0); #endif }
/// <summary> /// with wardobeRecipes, DynamicCharacterSystem does not have a list of refrenced recipes like the other libraries /// so the only way to get them is from DynamicAssetLoader (which is how DCS gets them) /// so they MUST be in an assetBundle or in Global Index or there is no way of finding them /// </summary> /// <param name="recipeName"></param> /// <returns></returns> /// private UMARecipeBase FindMissingRecipe(string recipeName) { UMARecipeBase foundRecipe = null; //the following will find things like femaleHair1 if 'maleHair1' is the recipe name var foundWardrobeGUIDS = AssetDatabase.FindAssets("t:UMAWardrobeRecipe " + recipeName); if (foundWardrobeGUIDS.Length > 0) { foreach (string guid in foundWardrobeGUIDS) { var tempAsset = AssetDatabase.LoadAssetAtPath <UMAWardrobeRecipe>(AssetDatabase.GUIDToAssetPath(guid)); if (tempAsset.name == recipeName) { foundRecipe = tempAsset; break; } } } //try searching for WardrobeCollections if (foundRecipe == null) { var foundWardrobeCollectionGUIDS = AssetDatabase.FindAssets("t:UMAWardrobeCollection " + recipeName); if (foundWardrobeCollectionGUIDS.Length > 0) { foreach (string guid in foundWardrobeCollectionGUIDS) { var tempAsset = AssetDatabase.LoadAssetAtPath <UMAWardrobeCollection>(AssetDatabase.GUIDToAssetPath(guid)); if (tempAsset.name == recipeName) { foundRecipe = tempAsset; break; } } } } return(foundRecipe); }
private void UpdateAvatar() { if (null == avatar) { avatar = GetComponent <DynamicCharacterAvatar>(); if (null != avatar) { List <UMARecipeBase> recipes = new List <UMARecipeBase>(); for (int idx = avatar.umaAdditionalRecipes.Length - 1; idx >= 0; idx--) { UMARecipeBase recipe = avatar.umaAdditionalRecipes[idx]; Debug.Log(recipe.name); if (recipe.name != "CapsuleColliderRecipe") { recipes.Add(recipe); } } avatar.umaAdditionalRecipes = recipes.ToArray(); avatar.CharacterCreated.AddListener(OnUmaReady); avatar.CharacterDestroyed.AddListener(OnUmaDestroyed); avatar.raceAnimationControllers.defaultAnimationController = runtimeAnimationController; } } }
public static GameObject GetPreview(UMARecipeBase recipeBase) { return(GameObject.Find("PowerTools_" + recipeBase.name)); }
private void IncludeRecipe(UMARecipeBase recipe, UMAData.UMARecipe umaRecipe, UMAContextBase context, bool dontSerialize) { UMAData.UMARecipe cachedRecipe = recipe.GetCachedRecipe(context); umaRecipe.Merge(cachedRecipe, dontSerialize); }
// Drop area for Arbitrary Wardrobe recipes private bool AddRecipesDropAreaGUI(ref string errorMsg, Rect dropArea, List <string> recipes) { Event evt = Event.current; bool changed = false; //make the box clickable so that the user can select raceData assets from the asset selection window //TODO: cant make this work without layout errors. Anyone know how to fix? /*if (evt.type == EventType.MouseUp) * { * if (dropArea.Contains(evt.mousePosition)) * { * recipePickerID = EditorGUIUtility.GetControlID(new GUIContent("recipeObjectPicker"), FocusType.Passive); * EditorGUIUtility.ShowObjectPicker<UMARecipeBase>(null, false, "", recipePickerID); * } * } * if (evt.commandName == "ObjectSelectorUpdated" && EditorGUIUtility.GetObjectPickerControlID() == recipePickerID) * { * UMARecipeBase tempRecipeAsset = EditorGUIUtility.GetObjectPickerObject() as UMARecipeBase; * if (tempRecipeAsset) * { * if (AddIfWardrobeRecipe(tempRecipeAsset, recipes)) * { * changed = true; * errorMsg = ""; * } * else * errorMsg = "That recipe was not a Wardrobe recipe"; * * } * }*/ if (evt.type == EventType.DragUpdated) { if (dropArea.Contains(evt.mousePosition)) { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; } } if (evt.type == EventType.DragPerform) { if (dropArea.Contains(evt.mousePosition)) { DragAndDrop.AcceptDrag(); UnityEngine.Object[] draggedObjects = DragAndDrop.objectReferences as UnityEngine.Object[]; bool allAdded = true; for (int i = 0; i < draggedObjects.Length; i++) { if (draggedObjects[i]) { UMARecipeBase tempRecipeAsset = draggedObjects[i] as UMARecipeBase; if (tempRecipeAsset) { if (AddIfWardrobeRecipe(tempRecipeAsset, recipes)) { changed = true; } else { allAdded = false; } continue; } var path = AssetDatabase.GetAssetPath(draggedObjects[i]); if (System.IO.Directory.Exists(path)) { RecursiveScanFoldersForAssets(path, recipes); } } } if (!allAdded) { errorMsg = "Some of the recipes you tried to add were not Wardrobe recipes"; } else { errorMsg = ""; } } } return(changed); }
public static bool HasPreview(UMARecipeBase recipeBase) { return(GetPreview(recipeBase) != null); }
protected void CreateBonePoseCallback(UMAData umaData) { UMA.PoseTools.UMABonePose bonePose = null; 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(); // Set this asset as the converters pose asset selectedConverter.startingPose = bonePose; //make sure its fully applied selectedConverter.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?", "Remove DNA", "Keep DNA")) { UMAData.UMARecipe baseRecipeData = new UMAData.UMARecipe(); baseRaceRecipe.Load(baseRecipeData, activeUMA.context); baseRecipeData.ClearDna(); baseRaceRecipe.Save(baseRecipeData, activeUMA.context); } } }
private void UpdateBackwardsCompatibleData() { var context = UMAContextBase.Instance; if (context == null) { var _errorMessage = "Editing a recipe requires a loaded scene with a valid UMAContextBase."; Debug.LogWarning(_errorMessage); } //reset the recipe to the raceBase recipe var thisBaseRecipe = _recipe.raceData.baseRaceRecipe; thisBaseRecipe.Load(_recipe, context); if (_wardrobeSet.Count > 0) { List <UMARecipeBase> Recipes = new List <UMARecipeBase>(); List <string> SuppressSlotsStrings = new List <string>(); List <string> HiddenSlots = new List <string>(); var wardrobeRecipesToRender = new Dictionary <string, UMARecipeBase>(); var activeRace = _recipe.raceData.raceName; //Dont add the WardrobeCollection to the recipes to render- they doesn't render directly and will have already set their actual wardrobeRecipe slots SetSlot foreach (WardrobeSettings set in _wardrobeSet) { var thisRecipe = UMAContext.Instance.GetBaseRecipe(set.recipe, true); if (thisRecipe == null) { continue; } if (thisRecipe.GetType().ToString() == "UMA.UMAWardrobeCollection") { var TargetType = thisRecipe.GetType(); FieldInfo WardrobeCollectionField = TargetType.GetField("wardrobeCollection", BindingFlags.Public | BindingFlags.Instance); WardrobeCollectionList wardrobeCollection = (WardrobeCollectionList)WardrobeCollectionField.GetValue(thisRecipe); if (wardrobeCollection[activeRace] != null) { foreach (WardrobeSettings ws in wardrobeCollection[activeRace]) { var wsRecipe = UMAContext.Instance.GetBaseRecipe(ws.recipe, true); if (wsRecipe != null) { if (wardrobeRecipesToRender.ContainsKey(ws.slot)) { wardrobeRecipesToRender[ws.slot] = wsRecipe; } else { wardrobeRecipesToRender.Add(ws.slot, wsRecipe); } } } } } else { //_recipe.Merge(thisRecipe.GetCachedRecipe(context), true); if (wardrobeRecipesToRender.ContainsKey(set.slot)) { wardrobeRecipesToRender[set.slot] = thisRecipe; } else { wardrobeRecipesToRender.Add(set.slot, thisRecipe); } } } if (wardrobeRecipesToRender.Count > 0) { foreach (UMARecipeBase utr in wardrobeRecipesToRender.Values) { var TargetType = utr.GetType(); FieldInfo CompatibleRacesField = TargetType.GetField("compatibleRaces", BindingFlags.Public | BindingFlags.Instance); FieldInfo WardrobeSlotField = TargetType.GetField("wardrobeSlot", BindingFlags.Public | BindingFlags.Instance); FieldInfo SuppressWardrobeSlotField = TargetType.GetField("suppressWardrobeSlots", BindingFlags.Public | BindingFlags.Instance); //field values List <string> compatibleRaces = (List <string>)CompatibleRacesField.GetValue(utr); string wardrobeSlot = (string)WardrobeSlotField.GetValue(utr); List <string> suppressWardrobeSlot = (List <string>)SuppressWardrobeSlotField.GetValue(utr); if (suppressWardrobeSlot != null) { if (activeRace == "" || ((compatibleRaces.Count == 0 || compatibleRaces.Contains(activeRace)) || (_recipe.raceData.IsCrossCompatibleWith(compatibleRaces) && _recipe.raceData.wardrobeSlots.Contains(wardrobeSlot)))) { if (!SuppressSlotsStrings.Contains(wardrobeSlot)) { foreach (string suppressedSlot in suppressWardrobeSlot) { SuppressSlotsStrings.Add(suppressedSlot); } } } } } } foreach (string ws in _recipe.raceData.wardrobeSlots) { if (SuppressSlotsStrings.Contains(ws)) { continue; } if (wardrobeRecipesToRender.ContainsKey(ws)) { UMARecipeBase utr = wardrobeRecipesToRender[ws]; var TargetType = wardrobeRecipesToRender[ws].GetType(); FieldInfo CompatibleRacesField = TargetType.GetField("compatibleRaces", BindingFlags.Public | BindingFlags.Instance); FieldInfo WardrobeSlotField = TargetType.GetField("wardrobeSlot", BindingFlags.Public | BindingFlags.Instance); FieldInfo HidesField = TargetType.GetField("Hides", BindingFlags.Public | BindingFlags.Instance); //field values List <string> compatibleRaces = (List <string>)CompatibleRacesField.GetValue(utr); string wardrobeSlot = (string)WardrobeSlotField.GetValue(utr); List <string> hides = (List <string>)HidesField.GetValue(utr); if (activeRace == "" || ((compatibleRaces.Count == 0 || compatibleRaces.Contains(activeRace)) || (_recipe.raceData.IsCrossCompatibleWith(compatibleRaces) && _recipe.raceData.wardrobeSlots.Contains(wardrobeSlot)))) { Recipes.Add(utr); if (hides.Count > 0) { foreach (string s in hides) { HiddenSlots.Add(s); } } } } } //merge them in foreach (var additionalRecipe in Recipes) { _recipe.Merge(additionalRecipe.GetCachedRecipe(context), true); } if (HiddenSlots.Count > 0) { List <SlotData> NewSlots = new List <SlotData>(); foreach (SlotData sd in _recipe.slotDataList) { if (sd == null) { continue; } if (!HiddenSlots.Contains(sd.asset.slotName)) { NewSlots.Add(sd); } } _recipe.slotDataList = NewSlots.ToArray(); } ResetSlotEditors(); } }
/// <summary> /// Load a UMA recipe into the avatar. /// </summary> /// <param name="umaRecipe">UMA recipe.</param> public virtual void Load(UMARecipeBase umaRecipe) { Load(umaRecipe, null); }
public static bool HasPreview(UMARecipeBase recipeBase) { return GetPreview(recipeBase) != null; }
public static GameObject GetPreview(UMARecipeBase recipeBase) { return GameObject.Find("PowerTools_" + recipeBase.name); }
private void IncludeRecipe(UMARecipeBase recipe, UMAData.UMARecipe umaRecipe, UMAContext context, bool additional) { UMAData.UMARecipe cachedRecipe = recipe.GetCachedRecipe(context); umaRecipe.Merge(cachedRecipe, additional); }
// practical guide to UMA part 14b https://youtu.be/Q6bLMusuhbo?t=10m18s void LoadAsset() { UMARecipeBase recipe = Resources.Load("Troll") as UMARecipeBase; umaDynamicAvatar.Load(recipe); }
void OnGUI() { GUILayout.Label("UMA Bone Builder"); GUILayout.Space(20); newUmaObj = EditorGUILayout.ObjectField("UMA GameObject ", umaObject, typeof(GameObject), true) as GameObject; if (newUmaObj != umaObject) { umaObject = newUmaObj; if (newUmaObj != null) { _avatar = umaObject.GetComponent <DynamicCharacterAvatar>(); } } if (umaObject != null && _avatar == null) { EditorGUILayout.HelpBox("This UMA is not a DynamicCharacterAvatar so we need to supply the base recipe.", MessageType.Info); baseRecipe = EditorGUILayout.ObjectField("Base Recipe", baseRecipe, typeof(UMARecipeBase), false) as UMARecipeBase; } else { baseRecipe = null; } removeUMAData = EditorGUILayout.Toggle(new GUIContent("Remove UMAData", "A recipe and UMAData is created during the bone generation process, checking this will remove it at the end of the process. (Recommended)"), removeUMAData); if (GUILayout.Button("Generate Bones")) { if (umaObject == null) { Debug.LogWarning("UMA GameObject not set!"); return; } if (_avatar.activeRace.data == null) { Debug.LogWarning("No recipe data found. Make sure the race is added to the library!"); return; } if (_avatar != null) { baseRecipe = _avatar.activeRace.data.baseRaceRecipe; } if (baseRecipe == null) { Debug.LogWarning("BaseRecipe not set!"); return; } Debug.Log("Processing..."); InitializeUMAData(); FindBones(); EnsureRoot(); CreateBoneTransforms(); InitializeAnimator(); if (removeUMAData) { Cleanup(); } Debug.Log("Completed!"); } }
void OnGUI() { GUILayout.Label("UMA Bone Builder"); GUILayout.Space(20); if (Application.isPlaying) { EditorGUILayout.HelpBox("The bone builder should not be used while the scene is running.", MessageType.Info); return; } newUmaObj = EditorGUILayout.ObjectField("UMA GameObject ", umaObject, typeof(GameObject), true) as GameObject; //prevent being able to set set a prefab in the bone builder. It will not work. if (newUmaObj != null && EditorUtility.IsPersistent(newUmaObj)) { newUmaObj = null; } if (newUmaObj != umaObject) { umaObject = newUmaObj; if (newUmaObj != null) { _avatar = umaObject.GetComponent <DynamicCharacterAvatar>(); } } if (umaObject != null && _avatar == null) { EditorGUILayout.HelpBox("This UMA is not a DynamicCharacterAvatar so we need to supply the base recipe.", MessageType.Info); baseRecipe = EditorGUILayout.ObjectField("Base Recipe", baseRecipe, typeof(UMARecipeBase), false) as UMARecipeBase; } else { baseRecipe = null; } removeUMAData = EditorGUILayout.Toggle(new GUIContent("Remove UMAData", "A recipe and UMAData is created during the bone generation process, checking this will remove it at the end of the process. (Recommended)"), removeUMAData); // Currently, this produces an avatar with it's arms twisted. // saveAvatar = EditorGUILayout.Toggle(new GUIContent("Save Mecanim Avatar", "This will save the Mecanim Avatar generated as an asset."), saveAvatar); GUILayout.Label("You can save the avatar at runtime using the option on the UMA/Runtime menu.", EditorStyles.wordWrappedMiniLabel); if (GUILayout.Button("Generate Bones")) { if (umaObject == null) { Debug.LogWarning("UMA GameObject not set!"); return; } if (_avatar != null && _avatar.activeRace.data == null) { Debug.LogWarning("No recipe data found. Make sure the race is added to the library!"); return; } if (_avatar != null) { baseRecipe = _avatar.activeRace.data.baseRaceRecipe; } if (baseRecipe == null) { Debug.LogWarning("BaseRecipe not set!"); return; } Debug.Log("Processing..."); InitializeUMAData(); FindBones(); EnsureRoot(); CreateBoneTransforms(); InitializeAnimator(); if (removeUMAData) { Cleanup(); } Debug.Log("Completed!"); this.Close(); } }
/// <summary> /// Simple Asset Loader /// </summary> public void LoadAsset() { UMARecipeBase recipe = Resources.Load(AssetName) as UMARecipeBase; umaDynamicAvatar.Load(recipe); }
// practical guide to UMA part 14b https://youtu.be/Q6bLMusuhbo?t=10m18s void LoadAsset() { UMARecipeBase recipe = Resources.Load("Assets/UMASavedAsAsset.asset") as UMARecipeBase; umaDynamicAvatar.Load(recipe); }
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); } } } }
/// <summary> /// Load a UMA recipe and additional recipes into the avatar. /// </summary> /// <param name="umaRecipe">UMA recipe.</param> /// <param name="umaAdditionalRecipes">Additional recipes.</param> public virtual void Load(UMARecipeBase umaRecipe, params UMARecipeBase[] umaAdditionalRecipes) { if (umaRecipe == null) return; if (umaData == null) { Initialize(); } Profiler.BeginSample("Load"); this.umaRecipe = umaRecipe; umaRecipe.Load(umaData.umaRecipe, context); umaData.AddAdditionalRecipes(umaAdditionalRecipes, context); if (umaRace != umaData.umaRecipe.raceData) { UpdateNewRace(); } else { UpdateSameRace(); } Profiler.EndSample(); }