public OverlayEditor(UMAData.UMARecipe recipe, SlotData slotData, OverlayData overlayData) { _recipe = recipe; _overlayData = overlayData; _slotData = slotData; _sharedColors = false; if (_recipe.sharedColors != null) { foreach (OverlayColorData ocd in _recipe.sharedColors) { if (ocd.GetHashCode() == _overlayData.colorData.GetHashCode()) { _sharedColors = true; } } } if (_sharedColors && (_overlayData.colorData.name == OverlayColorData.UNSHARED)) { _sharedColors = false; } _textures = new TextureEditor[overlayData.asset.textureList.Length]; for (int i = 0; i < overlayData.asset.textureList.Length; i++) { _textures[i] = new TextureEditor(overlayData.asset.textureList[i]); } BuildColorEditors(); }
//This is used when an inspected recipe asset is saved public override void Save(UMAData.UMARecipe umaRecipe, UMAContext context) { if (recipeType == "Wardrobe") //Wardrobe Recipes can save the standard UMA way- they dont have WardrobeSets- although the recipe string wont have a packedRecipeType field { base.Save(umaRecipe, context); } else if (recipeType != "Standard") //this will just be for type DynamicCharacterAvatar- and WardrobeCollection if we add that { var packedRecipe = PackRecipeV2(umaRecipe); //DCSPackRecipe doesn't do any more work, it just gets the values from PackRecipeV2 that we need and discards the rest var packedRecipeToSave = new DCSPackRecipe(packedRecipe, this.name, recipeType, activeWardrobeSet); recipeString = JsonUtility.ToJson(packedRecipeToSave); } else //This will be Standard- this is 'backwards Compatible' and is also how the Recipe Editor saves 'backwardsCompatible' 'Standard' recipes when they are inspected { umaRecipe.MergeMatchingOverlays(); var packedRecipe = PackRecipeV2(umaRecipe); var packedRecipeToSave = new DCSUniversalPackRecipe(packedRecipe); //this gets us a recipe with all the standard stuff plus our extra fields //so now we can save the wardrobeSet into it if it existed if (activeWardrobeSet != null) { if (activeWardrobeSet.Count > 0) { packedRecipeToSave.wardrobeSet = activeWardrobeSet; } } recipeString = JsonUtility.ToJson(packedRecipeToSave); } }
public WardrobeSetEditor(RaceData race, List <WardrobeSettings> wardrobeSet, UMAData.UMARecipe recipe, bool allowWardrobeCollectionSlot) { _recipe = recipe; _wardrobeSet = wardrobeSet; _race = race; _allowWardrobeCollectionSlot = allowWardrobeCollectionSlot; }
public SlotMasterEditor(UMAData.UMARecipe recipe) { _recipe = recipe; if (recipe.slotDataList == null) { recipe.slotDataList = new SlotData[0]; } for (int i = 0; i < recipe.slotDataList.Length; i++) { var slot = recipe.slotDataList[i]; if (slot == null) { continue; } _slotEditors.Add(new SlotEditor(_recipe, slot, i)); } _slotEditors.Sort(SlotEditor.comparer); if (_slotEditors.Count > 1) { var overlays1 = _slotEditors[0].GetOverlays(); var overlays2 = _slotEditors[1].GetOverlays(); for (int i = 0; i < _slotEditors.Count - 2; i++) { if (overlays1 == overlays2) { _slotEditors[i].sharedOverlays = true; } overlays1 = overlays2; overlays2 = _slotEditors[i + 2].GetOverlays(); } } }
public void OnEnable() { if (!NeedsReenable()) { return; } _errorMessage = null; _recipe = new UMAData.UMARecipe(); showBaseEditor = false; try { var umaRecipeBase = target as UMARecipeBase; if (umaRecipeBase != null) { umaRecipeBase.Load(_recipe, UMAContext.FindInstance()); _description = umaRecipeBase.GetInfo(); } } catch (UMAResourceNotFoundException e) { _errorMessage = e.Message; } dnaEditor = new DNAMasterEditor(_recipe); slotEditor = new SlotMasterEditor(_recipe); _rebuildOnLayout = true; }
//private List<CheckedMaterial> Materials = new List<CheckedMaterial>(); void Refresh() { Context = UMAContext.FindInstance(); if (Context == null) { EditorUtility.DisplayDialog("Error", "There is no UMA Context in the current scene!", "OK"); return; } Slots.Clear(); if (Race == null) { EditorUtility.DisplayDialog("Error", "No RaceData selected!", "OK"); return; } Recipe = new UMAData.UMARecipe(); Race.baseRaceRecipe.Load(Recipe, Context); if (Recipe == null) { return; } foreach (SlotData s in Recipe.slotDataList) { if (s == null) { continue; } Slots.Add(new CheckedSlot(s, true)); } }
public void OnEnable() { if (!NeedsReenable()) return; _errorMessage = null; _recipe = new UMAData.UMARecipe(); showBaseEditor = false; try { var umaRecipeBase = target as UMARecipeBase; if (umaRecipeBase != null) { var context = UMAContext.FindInstance() ; if (context == null) { _recipe = null; return; } umaRecipeBase.Load(_recipe, context); _description = umaRecipeBase.GetInfo(); } } catch (UMAResourceNotFoundException e) { _errorMessage = e.Message; } dnaEditor = new DNAMasterEditor(_recipe); slotEditor = new SlotMasterEditor(_recipe); _rebuildOnLayout = true; }
/// <summary> /// Searches the recipe of the current active race for all its slots and builds a list of available bones from the slots meshData /// </summary> public void UpdateSeverablesFromActiveRecipe(string[] filters = null) { Debug.Log("UpdateSeverablesFromActiveRecipe for " + _characterAvatar.activeRace.name); var umaSeverablesList = new List <UMATransform>(); var selectedUmaSeverablesList = new List <UMATransform>(); UMAData.UMARecipe umaRecipe = new UMAData.UMARecipe(); _characterAvatar.activeRace.data.baseRaceRecipe.Load(umaRecipe, _characterAvatar.context); foreach (SlotData slot in umaRecipe.GetAllSlots()) { if (slot == null || slot.asset == null || slot.asset.meshData == null || slot.asset.meshData.umaBones == null) { continue; } //UMATransform doesn't have a System.IEquatable<UMATransform> so we have to compare by hash foreach (UMATransform umaTrans in slot.asset.meshData.umaBones) { //Find out if umaSeverablesList already has this UMATransform in it bool canAdd = !IsUMATransformInList(umaTrans, umaSeverablesList); if (canAdd) { //filter out any bones we dont want if (filters != null) { for (int fi = 0; fi < filters.Length; fi++) { if (!string.IsNullOrEmpty(filters[fi]) && umaTrans.name.IndexOf(filters[fi]) > -1) { canAdd = false; } } } if (canAdd) { umaSeverablesList.Add(umaTrans); } } } } if (_cachedRaceSeverables.ContainsKey(_characterAvatar.activeRace.name)) { //used the cached UMATransforms if we have them selectedUmaSeverablesList = new List <UMATransform>(_cachedRaceSeverables[_characterAvatar.activeRace.name]); } else { //only add any selected UMATrans that are in the new list for (int i = 0; i < _selectedUmaSeverables.Length; i++) { if (IsUMATransformInList(_selectedUmaSeverables[i], umaSeverablesList)) { selectedUmaSeverablesList.Add(_selectedUmaSeverables[i]); } } } //can we sort _umaSeverables so it reflects the bone heirarcy? Its pretty horrible like this. Probably can since each bone contains 'parent' data _umaSeverables = SortUMASeverablesList(umaSeverablesList).ToArray(); _selectedUmaSeverables = selectedUmaSeverablesList.ToArray(); }
//int recipePickerID = -1; This is needed if we can make the recipe drop area work with 'Click To Pick' public WardrobeCollectionMasterEditor(UMAData.UMARecipe recipe, List <string> compatibleRaces, WardrobeCollectionList wardrobeCollection, List <string> arbitraryRecipes) : base(recipe) { _compatibleRaces = compatibleRaces; _wardrobeCollection = wardrobeCollection; _arbitraryRecipes = arbitraryRecipes; UpdateFoldouts(); recipesAddErrMsg = ""; }
public override void OnEnable() { if (plugins == null) { AddPlugins(); } base.OnEnable(); foreach (IUMARecipePlugin plugin in plugins) { plugin.OnEnable(); } if (!NeedsReenable()) { return; } _errorMessage = null; _recipe = new UMAData.UMARecipe(); showBaseEditor = false; try { var umaRecipeBase = target as UMARecipeBase; if (umaRecipeBase != null) { var context = UMAContextBase.Instance; //create a virtual UMAContextBase if we dont have one and we have DCS if (context == null || context.gameObject.name == "UMAEditorContext") { context = umaRecipeBase.CreateEditorContext(); //will create or update an UMAEditorContext to the latest version generatedContext = context.gameObject.transform.parent.gameObject; //The UMAContextBase in a UMAEditorContext is that gameobject's child } //legacy checks for context if (context == null) { _errorMessage = "Editing a recipe requires a loaded scene with a valid UMAContextBase."; Debug.LogWarning(_errorMessage); //_recipe = null; //return; } umaRecipeBase.Load(_recipe, context); _description = umaRecipeBase.GetInfo(); } } catch (UMAResourceNotFoundException e) { _errorMessage = e.Message; } dnaEditor = new DNAMasterEditor(_recipe); slotEditor = new SlotMasterEditor(_recipe); _rebuildOnLayout = true; }
//TODO: once everyone has their recipes updated remove this- we only want UMATextRecipes to save as 'Standard' /// <summary> /// Saves a 'Standard' UMATextRecipe. If saving a DynamicCharacterAvatar as 'Backwards Compatible' this will save a recipe that has slots/overlay data AND a wardrobe set /// </summary> public void Save(UMAData.UMARecipe umaRecipe, UMAContext context, Dictionary <string, UMATextRecipe> wardrobeRecipes, bool backwardsCompatible = true) { if (wardrobeRecipes.Count > 0) { activeWardrobeSet = GenerateWardrobeSet(wardrobeRecipes); } recipeType = backwardsCompatible ? "Standard" : "DynamicCharacterAvatar"; Save(umaRecipe, context); }
/// <summary> /// Return a cached version of the UMA recipe, Load if required. /// </summary> /// <returns>The cached recipe.</returns> /// <param name="context">Context.</param> public UMAData.UMARecipe GetCachedRecipe(UMAContext context) { if (!cached) { umaRecipe = new UMAData.UMARecipe(); Load(umaRecipe, context); } return(umaRecipe); }
/// <summary> /// Return a cached version of the UMA recipe, Load if required. /// </summary> /// <returns>The cached recipe.</returns> /// <param name="context">Context.</param> public UMAData.UMARecipe GetCachedRecipe(UMAContext context) { if (!cached) { umaRecipe = new UMAData.UMARecipe(); Load(umaRecipe, context); } return umaRecipe; }
//generate an option list for the BaseSlots that are available to hide for each race so we can make this a mask field too private void GenerateBaseSlotsEnum(List <string> compatibleRaces, bool forceUpdate = false) { if (generatedBaseSlotOptions.Count == 0 || forceUpdate) { //clear the lists if we are forcing update if (forceUpdate) { generatedBaseSlotOptions = new List <string>(); generatedBaseSlotOptionsLabels = new List <string>(); } List <UMARecipeBase> thisBaseRecipes = new List <UMARecipeBase>(); Dictionary <string, List <string> > slotsRacesDict = new Dictionary <string, List <string> >(); for (int i = 0; i < compatibleRaces.Count; i++) { if (GetCompatibleRaceData(compatibleRaces[i]) == null) { continue; } thisBaseRecipes.Add(GetCompatibleRaceData(compatibleRaces[i]).baseRaceRecipe); } for (int i = 0; i < thisBaseRecipes.Count; i++) { if (thisBaseRecipes[i] != null) { UMAData.UMARecipe thisBaseRecipe = thisBaseRecipes[i].GetCachedRecipe(UMAContext.Instance); SlotData[] thisSlots = thisBaseRecipe.GetAllSlots(); foreach (SlotData slot in thisSlots) { if (slot != null) { if (!generatedBaseSlotOptions.Contains(slot.asset.slotName)) { generatedBaseSlotOptions.Add(slot.asset.slotName); } if (!slotsRacesDict.ContainsKey(slot.asset.slotName)) { slotsRacesDict.Add(slot.asset.slotName, new List <string>()); } slotsRacesDict[slot.asset.slotName].Add(compatibleRaces[i]); } } } } //sort out the labels showing which race(s) the base slots are for if there is more than one compatible race foreach (KeyValuePair <string, List <string> > kp in slotsRacesDict) { string compatibleRaceNames = ""; if (compatibleRaces.Count > 1) { compatibleRaceNames = " (" + String.Join(", ", kp.Value.ToArray()) + ")"; } generatedBaseSlotOptionsLabels.Add(kp.Key + compatibleRaceNames); } } }
/// <summary> /// Fills in a UMA recipe with random partial fragments from the sections. /// </summary> /// <param name="umaRecipe">UMA recipe.</param> /// <param name="context">Context.</param> public void FillUMARecipe(UMAData.UMARecipe umaRecipe, UMAContextBase context) { if (raceData == null) { Debug.LogWarning("Race Data must be set!"); return; } umaRecipe.SetRace(raceData); int sectionCount = (recipeSections == null) ? 0 : recipeSections.Length; for (int i = 0; i < sectionCount; i++) { RecipeSection section = recipeSections[i]; if ((section.recipes == null) || (section.recipes.Length == 0)) { continue; } switch (section.selectionRule) { case SelectionType.IncludeNone: break; case SelectionType.IncludeAll: for (int j = 0; j < section.recipes.Length; j++) { IncludeRecipe(section.recipes[j], umaRecipe, context, false); } break; case SelectionType.IncludeSome: float chance = 1f / (float)(section.recipes.Length + 1); for (int j = 0; j < section.recipes.Length; j++) { if (Random.value < chance) { IncludeRecipe(section.recipes[j], umaRecipe, context, false); } } break; case SelectionType.IncludeOne: default: int index = Random.Range(0, section.recipes.Length); IncludeRecipe(section.recipes[index], umaRecipe, context, false); break; } } for (int i = 0; i < additionalRecipes.Length; i++) { IncludeRecipe(additionalRecipes[i], umaRecipe, context, true); } }
/// <summary> /// Adds the shared colors from a given recipe name into the target recipe /// </summary> /// <param name="sourceRecipeName"></param> /// <param name="targetRecipe"></param> protected virtual bool AddSharedColorsFromRecipe(string sourceRecipeName, UMAData.UMARecipe targetRecipe) { bool changed = false; var thisUmaDataRecipe = new UMAData.UMARecipe(); var context = UMAContextBase.Instance; if (context == null) { return(false); } var thisWardrobeRecipe = context.GetBaseRecipe(sourceRecipeName, true); if (thisWardrobeRecipe == null) { return(false); } try { thisWardrobeRecipe.Load(thisUmaDataRecipe, context); } catch { return(false); } if (thisUmaDataRecipe.sharedColors.Length > 0) { List <OverlayColorData> newSharedColors = new List <OverlayColorData>(); newSharedColors.AddRange(targetRecipe.sharedColors); for (int i = 0; i < thisUmaDataRecipe.sharedColors.Length; i++) { bool existed = false; for (int ii = 0; ii < newSharedColors.Count; ii++) { if (newSharedColors[ii].name == thisUmaDataRecipe.sharedColors[i].name) { existed = true; break; } } if (!existed) { newSharedColors.Add(thisUmaDataRecipe.sharedColors[i]); changed = true; } } if (changed) { targetRecipe.sharedColors = newSharedColors.ToArray(); } } return(changed); }
public void OnEnable() { if (!NeedsReenable()) { return; } _errorMessage = null; _recipe = new UMAData.UMARecipe(); showBaseEditor = false; try { var umaRecipeBase = target as UMARecipeBase; if (umaRecipeBase != null) { var context = UMAContext.FindInstance(); //create a virtual UMAContext if we dont have one and we have DCS if (context == null) { context = umaRecipeBase.CreateEditorContext(); generatedContext = context.gameObject.transform.parent.gameObject; } //legacy checks for context if (context == null) { _errorMessage = "Editing a recipe requires a loaded scene with a valid UMAContext."; Debug.LogWarning(_errorMessage); //_recipe = null; //return; } else if (context.raceLibrary == null) { _errorMessage = "Editing a recipe requires a loaded scene with a valid UMAContext with RaceLibrary assigned."; Debug.LogWarning(_errorMessage); //_recipe = null; //return; } umaRecipeBase.Load(_recipe, context); _description = umaRecipeBase.GetInfo(); } } catch (UMAResourceNotFoundException e) { _errorMessage = e.Message; } dnaEditor = new DNAMasterEditor(_recipe); slotEditor = new SlotMasterEditor(_recipe); _rebuildOnLayout = true; }
public SlotEditor(UMAData.UMARecipe recipe, SlotData slotData, int index) { _recipe = recipe; _slotData = slotData; _overlayData = slotData.GetOverlayList(); this.idx = index; _name = slotData.asset.slotName; for (int i = 0; i < _overlayData.Count; i++) { _overlayEditors.Add(new OverlayEditor(_recipe, slotData, _overlayData[i])); } }
public SlotMasterEditor(UMAData.UMARecipe recipe) { _recipe = recipe; foreach (var slot in recipe.slotDataList) { if (slot == null) { continue; } _slots.Add(new SlotEditor(slot)); } }
/* * public static UMAPackRecipe PackRecipeV1(UMA.UMAData.UMARecipe umaRecipe) * { * UMAPackRecipe umaPackRecipe = new UMAPackRecipe(); * * //var umaPackRecipe = new Packed * int slotCount = umaRecipe.slotDataList.Length - umaRecipe.AdditionalSlots; * umaPackRecipe.packedSlotDataList = new packedSlotData[slotCount]; * umaPackRecipe.race = umaRecipe.raceData.raceName; * * foreach (var dna in umaRecipe.GetAllDna()) * { * UMAPackedDna packedDna = new UMAPackedDna(); * packedDna.dnaType = dna.GetType().Name; * packedDna.packedDna = UMA.UMADna.SaveInstance(dna); * umaPackRecipe.packedDna.Add(packedDna); * } * * for (int i = 0; i < slotCount; i++) * { * if (umaRecipe.slotDataList[i] != null) * { * packedSlotData tempPackedSlotData = new packedSlotData(); * umaPackRecipe.packedSlotDataList[i] = tempPackedSlotData; * * tempPackedSlotData.slotID = umaRecipe.slotDataList[i].asset.slotName; * tempPackedSlotData.overlayScale = Mathf.FloorToInt(umaRecipe.slotDataList[i].overlayScale * 100); * * bool copiedOverlays = false; * for (int i2 = 0; i2 < i; i2++) * { * if (umaRecipe.slotDataList[i2] != null && umaPackRecipe.packedSlotDataList[i2] != null) * { * if (umaRecipe.slotDataList[i].GetOverlayList() == umaRecipe.slotDataList[i2].GetOverlayList()) * { * tempPackedSlotData.copyOverlayIndex = i2; * copiedOverlays = true; * break; * } * } * } * if( copiedOverlays ) continue; * * tempPackedSlotData.OverlayDataList = new packedOverlayData[umaRecipe.slotDataList[i].OverlayCount]; * * for (int overlayID = 0; overlayID < tempPackedSlotData.OverlayDataList.Length; overlayID++) * { * tempPackedSlotData.OverlayDataList[overlayID] = new packedOverlayData(); * tempPackedSlotData.OverlayDataList[overlayID].overlayID = umaRecipe.slotDataList[i].GetOverlay(overlayID).asset.overlayName; * OverlayColorData colorData = umaRecipe.slotDataList[i].GetOverlay(overlayID).colorData; * if (colorData.color != Color.white) * { * Color32 color = umaRecipe.slotDataList[i].GetOverlay(overlayID).colorData.color; * tempPackedSlotData.OverlayDataList[overlayID].colorList = new int[4]; * tempPackedSlotData.OverlayDataList[overlayID].colorList[0] = color.r; * tempPackedSlotData.OverlayDataList[overlayID].colorList[1] = color.g; * tempPackedSlotData.OverlayDataList[overlayID].colorList[2] = color.b; * tempPackedSlotData.OverlayDataList[overlayID].colorList[3] = color.a; * } * * if (umaRecipe.slotDataList[i].GetOverlay(overlayID).rect != new Rect(0, 0, 0, 0)) * { * //Might need float in next version * tempPackedSlotData.OverlayDataList[overlayID].rectList = new int[4]; * tempPackedSlotData.OverlayDataList[overlayID].rectList[0] = (int)umaRecipe.slotDataList[i].GetOverlay(overlayID).rect.x; * tempPackedSlotData.OverlayDataList[overlayID].rectList[1] = (int)umaRecipe.slotDataList[i].GetOverlay(overlayID).rect.y; * tempPackedSlotData.OverlayDataList[overlayID].rectList[2] = (int)umaRecipe.slotDataList[i].GetOverlay(overlayID).rect.width; * tempPackedSlotData.OverlayDataList[overlayID].rectList[3] = (int)umaRecipe.slotDataList[i].GetOverlay(overlayID).rect.height; * } * * if (colorData.channelMask != null && colorData.channelMask.Length > 0) * { * tempPackedSlotData.OverlayDataList[overlayID].channelMaskList = new int[colorData.channelMask.Length][]; * * for (int channelAdjust = 0; channelAdjust < colorData.channelMask.Length; channelAdjust++) * { * tempPackedSlotData.OverlayDataList[overlayID].channelMaskList[channelAdjust] = new int[4]; * tempPackedSlotData.OverlayDataList[overlayID].channelMaskList[channelAdjust][0] = colorData.channelMask[channelAdjust].r; * tempPackedSlotData.OverlayDataList[overlayID].channelMaskList[channelAdjust][1] = colorData.channelMask[channelAdjust].g; * tempPackedSlotData.OverlayDataList[overlayID].channelMaskList[channelAdjust][2] = colorData.channelMask[channelAdjust].b; * tempPackedSlotData.OverlayDataList[overlayID].channelMaskList[channelAdjust][3] = colorData.channelMask[channelAdjust].a; * } * * } * if (colorData.channelAdditiveMask != null) * { * tempPackedSlotData.OverlayDataList[overlayID].channelAdditiveMaskList = new int[colorData.channelAdditiveMask.Length][]; * for (int channelAdjust = 0; channelAdjust < colorData.channelAdditiveMask.Length; channelAdjust++) * { * tempPackedSlotData.OverlayDataList[overlayID].channelAdditiveMaskList[channelAdjust] = new int[4]; * tempPackedSlotData.OverlayDataList[overlayID].channelAdditiveMaskList[channelAdjust][0] = colorData.channelAdditiveMask[channelAdjust].r; * tempPackedSlotData.OverlayDataList[overlayID].channelAdditiveMaskList[channelAdjust][1] = colorData.channelAdditiveMask[channelAdjust].g; * tempPackedSlotData.OverlayDataList[overlayID].channelAdditiveMaskList[channelAdjust][2] = colorData.channelAdditiveMask[channelAdjust].b; * tempPackedSlotData.OverlayDataList[overlayID].channelAdditiveMaskList[channelAdjust][3] = colorData.channelAdditiveMask[channelAdjust].a; * } * * } * } * } * } * return umaPackRecipe; * } */ public static List <UMAPackedDna> GetPackedDNA(UMAData.UMARecipe umaRecipe) { List <UMAPackedDna> PackedDNAlist = new List <UMAPackedDna>(); foreach (var dna in umaRecipe.GetAllDna()) { UMAPackedDna packedDna = new UMAPackedDna(); //DynamicUMADna:: needs the typeHash as this is randomly generated by the DynamicDnaConverter packedDna.dnaTypeHash = dna.DNATypeHash; packedDna.dnaType = dna.GetType().Name; packedDna.packedDna = UMA.UMADna.SaveInstance(dna); PackedDNAlist.Add(packedDna); } return(PackedDNAlist); }
protected virtual void Rebuild() { _rebuildOnLayout = false; if (_recipe != null) { int oldViewDNA = dnaEditor.viewDna; UMAData.UMARecipe oldRecipe = dnaEditor.recipe; dnaEditor = new DNAMasterEditor(_recipe); if (oldRecipe == _recipe) { dnaEditor.viewDna = oldViewDNA; } slotEditor = new SlotMasterEditor(_recipe); } }
/// <summary> /// This is used to save a DCS avatar to a 'backwards compatible' UMA model /// </summary> /// <param name="recipeToSave"></param> /// <param name="wardrobeRecipes"></param> /// <param name="recipeType"></param> public DCSUniversalPackRecipe(UMAData.UMARecipe recipeToSave, Dictionary <string, UMATextRecipe> wardrobeRecipes = null, string pRecipeType = "DynamicCharacterAvatar") { ///Debug.Log("Created universal model from Avatar"); var packedRecipe = PackRecipeV2(recipeToSave); packedRecipeType = pRecipeType; version = packedRecipe.version; packedSlotDataList = packedRecipe.packedSlotDataList; slotsV2 = packedRecipe.slotsV2; colors = packedRecipe.colors; fColors = packedRecipe.fColors; sharedColorCount = packedRecipe.sharedColorCount; race = packedRecipe.race; umaDna = packedRecipe.umaDna; packedDna = packedRecipe.packedDna; wardrobeSet = GenerateWardrobeSet(wardrobeRecipes); }
public DNAMasterEditor(UMAData.UMARecipe recipe) { this.recipe = recipe; UMADnaBase[] allDna = recipe.GetAllDna(); _dnaTypes = new Type[allDna.Length]; _dnaTypeNames = new string[allDna.Length]; for (int i = 0; i < allDna.Length; i++) { var entry = allDna[i]; var entryType = entry.GetType(); _dnaTypes[i] = entryType; _dnaTypeNames[i] = entryType.Name; _dnaValues[entryType] = new DNASingleEditor(entry); } }
public RaceData GetRaceData(Sex sex, UMAContext context) { RaceData data = null; lock (_raceData) { if (_raceData.ContainsKey(sex)) { return(_raceData[sex]); } UMARecipeBase recipe; switch (sex) { case Sex.Male: recipe = Male; break; case Sex.Female: recipe = Female; break; default: recipe = Other; break; } if (recipe != null) { var umaData = new UMAData.UMARecipe(); recipe.Load(umaData, context); data = umaData.raceData; _raceData[sex] = data; } } return(data); }
UMAData.UMARecipe CreateMaleRecipe() { var recipe = new UMAData.UMARecipe(); recipe.slotDataList = new SlotData[numberOfSlots]; recipe.AddDna(umaDna); recipe.AddDna(umaTutorialDna); recipe.SetRace(raceLibrary.GetRace("HumanMale")); SlotData eyes = slotLibrary.InstantiateSlot("MaleEyes"); eyes.AddOverlay(overlayLibrary.InstantiateOverlay("EyeOverlay")); recipe.slotDataList[0] = eyes; SlotData mouth = slotLibrary.InstantiateSlot("MaleInnerMouth"); mouth.AddOverlay(overlayLibrary.InstantiateOverlay("InnerMouth")); recipe.slotDataList[1] = mouth; recipe.slotDataList[2] = slotLibrary.InstantiateSlot("MaleFace", new List <OverlayData> { overlayLibrary.InstantiateOverlay("MaleHead02"), overlayLibrary.InstantiateOverlay("MaleEyebrow01", Color.black) });; SlotData torso = slotLibrary.InstantiateSlot("MaleTorso", new List <OverlayData> { overlayLibrary.InstantiateOverlay("MaleBody02"), overlayLibrary.InstantiateOverlay("MaleUnderwear01") }); recipe.slotDataList[3] = torso; recipe.slotDataList[4] = slotLibrary.InstantiateSlot("MaleHands", torso.GetOverlayList()); recipe.slotDataList[5] = slotLibrary.InstantiateSlot("MaleLegs", torso.GetOverlayList()); recipe.slotDataList[6] = slotLibrary.InstantiateSlot("MaleFeet", torso.GetOverlayList()); return(recipe); }
public OverlayEditor(UMAData.UMARecipe recipe, SlotData slotData, OverlayData overlayData) { _recipe = recipe; _overlayData = overlayData; _slotData = slotData; _sharedColors = false; if (_recipe.sharedColors != null) { _sharedColors = ArrayUtility.Contains <OverlayColorData>(_recipe.sharedColors, _overlayData.colorData); } if (_sharedColors && (_overlayData.colorData.name == OverlayColorData.UNSHARED)) { _sharedColors = false; } _textures = new TextureEditor[overlayData.asset.textureList.Length]; for (int i = 0; i < overlayData.asset.textureList.Length; i++) { _textures[i] = new TextureEditor(overlayData.asset.textureList[i]); } BuildColorEditors(); }
public static void FixUpUMADnaToDynamicUMADna(UMAData.UMARecipe _recipe) { var recipeDNA = _recipe.GetAllDna(); for (int i = 0; i < recipeDNA.Length; i++) { //if (!_recipe.raceData.raceDictionary.ContainsKey(recipeDNA[i].GetType())) //A RaceData may contain multiple DynamicDnaConverters use GetConverter instead and use the hash if (_recipe.raceData.GetConverter(recipeDNA[i]) == null) { int dnaToImport = recipeDNA[i].Count; int dnaImported = 0; for (int j = 0; j < recipeDNA.Length; j++) { if (recipeDNA[j] is DynamicUMADnaBase) { // Keep trying to find a new home for DNA values until they have all been set dnaImported += ((DynamicUMADnaBase)recipeDNA[j]).ImportUMADnaValues(recipeDNA[i]); if (dnaImported >= dnaToImport) { break; } } } if (dnaImported > 0) { if (_recipe.GetDna(recipeDNA[i].DNATypeHash) != null) { _recipe.RemoveDna(recipeDNA[i].DNATypeHash); } } } } }
public bool OnGUI(UMAData.UMARecipe _recipe) { GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); _foldout = EditorGUILayout.Foldout(_foldout, "Shared Colors"); GUILayout.EndHorizontal(); if (_foldout) { bool changed = false; GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); EditorGUILayout.BeginHorizontal(); if (_recipe.sharedColors == null) { _recipe.sharedColors = new OverlayColorData[0]; } if (_recipe.sharedColors.Length == 0) { selectedChannelCount = EditorGUILayout.IntPopup("Channels", selectedChannelCount, names, channels); } else { selectedChannelCount = _recipe.sharedColors [0].channelMask.Length; } if (GUILayout.Button("Add Shared Color")) { List <OverlayColorData> sharedColors = new List <OverlayColorData> (); sharedColors.AddRange(_recipe.sharedColors); sharedColors.Add(new OverlayColorData(selectedChannelCount)); _recipe.sharedColors = sharedColors.ToArray(); changed = true; } if (GUILayout.Button("Save Collection")) { changed = true; } EditorGUILayout.EndHorizontal(); if (_ColorFoldouts.Length != _recipe.sharedColors.Length) { Array.Resize <bool> (ref _ColorFoldouts, _recipe.sharedColors.Length); } for (int i = 0; i < _recipe.sharedColors.Length; i++) { bool del = false; OverlayColorData ocd = _recipe.sharedColors [i]; GUIHelper.FoldoutBar(ref _ColorFoldouts [i], i + ": " + ocd.name, out del); if (del) { List <OverlayColorData> temp = new List <OverlayColorData> (); temp.AddRange(_recipe.sharedColors); temp.RemoveAt(i); _recipe.sharedColors = temp.ToArray(); // TODO: search the overlays and adjust the shared colors break; } if (_ColorFoldouts [i]) { if (ocd.name == null) { ocd.name = ""; } string NewName = EditorGUILayout.TextField("Name", ocd.name); if (NewName != ocd.name) { ocd.name = NewName; //changed = true; } Color NewChannelMask = EditorGUILayout.ColorField("Color Multiplier", ocd.channelMask [0]); if (ocd.channelMask [0] != NewChannelMask) { ocd.channelMask [0] = NewChannelMask; changed = true; } Color NewChannelAdditiveMask = EditorGUILayout.ColorField("Color Additive", ocd.channelAdditiveMask [0]); if (ocd.channelAdditiveMask [0] != NewChannelAdditiveMask) { ocd.channelAdditiveMask [0] = NewChannelAdditiveMask; changed = true; } for (int j = 1; j < ocd.channelMask.Length; j++) { NewChannelMask = EditorGUILayout.ColorField("Texture " + j + "multiplier", ocd.channelMask [j]); if (ocd.channelMask [j] != NewChannelMask) { ocd.channelMask [j] = NewChannelMask; changed = true; } NewChannelAdditiveMask = EditorGUILayout.ColorField("Texture " + j + " additive", ocd.channelAdditiveMask [j]); if (ocd.channelAdditiveMask [j] != NewChannelAdditiveMask) { ocd.channelAdditiveMask [j] = NewChannelAdditiveMask; changed = true; } } } } GUIHelper.EndVerticalPadded(10); return(changed); } return(false); }
UMAData.UMARecipe CreateMaleRecipe() { var recipe = new UMAData.UMARecipe(); recipe.slotDataList = new SlotData[numberOfSlots]; recipe.AddDna(umaDna); recipe.AddDna(umaTutorialDna); recipe.SetRace(raceLibrary.GetRace("HumanMale")); SlotData eyes = slotLibrary.InstantiateSlot("MaleEyes"); eyes.AddOverlay(overlayLibrary.InstantiateOverlay("EyeOverlay")); recipe.slotDataList[0] = eyes; SlotData mouth = slotLibrary.InstantiateSlot("MaleInnerMouth"); mouth.AddOverlay(overlayLibrary.InstantiateOverlay("InnerMouth")); recipe.slotDataList[1] = mouth; recipe.slotDataList[2] = slotLibrary.InstantiateSlot("MaleFace", new List<OverlayData> { overlayLibrary.InstantiateOverlay("MaleHead02"), overlayLibrary.InstantiateOverlay("MaleEyebrow01", Color.black) });; SlotData torso = slotLibrary.InstantiateSlot("MaleTorso", new List<OverlayData> { overlayLibrary.InstantiateOverlay("MaleBody02"), overlayLibrary.InstantiateOverlay("MaleUnderwear01") }); recipe.slotDataList[3] = torso; recipe.slotDataList[4] = slotLibrary.InstantiateSlot("MaleHands", torso.GetOverlayList()); recipe.slotDataList[5] = slotLibrary.InstantiateSlot("MaleLegs", torso.GetOverlayList()); recipe.slotDataList[6] = slotLibrary.InstantiateSlot("MaleFeet", torso.GetOverlayList()); return recipe; }
public override void OnInspectorGUI() { serializedObject.Update(); MeshHideAsset source = target as MeshHideAsset; bool beginSceneEditing = false; //DrawDefaultInspector(); SlotDataAsset obj = EditorGUILayout.ObjectField("SlotDataAsset", source.asset, typeof(SlotDataAsset), false) as SlotDataAsset; if (obj != source.asset) { source.asset = obj as SlotDataAsset; if (_autoInitialize) { UpdateSourceAsset(obj); } } EditorGUILayout.LabelField("Slot Name", source.AssetSlotName.ToString()); if (source.HasReference) { EditorGUILayout.HelpBox("Warning: This Mesh Hide Asset contains a reference. It should be freed so the referenced asset is not included in the build.", MessageType.Warning); if (GUILayout.Button("Free Reference")) { source.FreeReference(); EditorUtility.SetDirty(source); AssetDatabase.SaveAssets(); } } _autoInitialize = EditorGUILayout.Toggle(new GUIContent("AutoInitialize (recommended)", "Checking this will auto initialize the MeshHideAsset when a slot is added (recommended). " + "For users that are rebuilding slots that don't change the geometry, the slot reference will be lost but can be reset without losing the existing MeshHide information by unchecking this."), _autoInitialize); if (source.asset == null) { EditorGUILayout.HelpBox("No SlotDataAsset set! Begin by adding a SlotDataAsset to the object field above.", MessageType.Error); } //Race Selector here GUILayout.Space(20); selectedRaceIndex = EditorGUILayout.Popup("Select Base Slot by Race", selectedRaceIndex, foundRaceNames.ToArray()); if (selectedRaceIndex <= 0) { EditorGUILayout.HelpBox("Quick selection of base slots by race. This is not needed to create a mesh hide asset, any slot can be used.", MessageType.Info); } else { UMAData.UMARecipe baseRecipe = new UMAData.UMARecipe(); foundRaces[selectedRaceIndex].baseRaceRecipe.Load(baseRecipe, UMAContextBase.Instance); foreach (SlotData sd in baseRecipe.slotDataList) { if (sd != null && sd.asset != null) { if (GUILayout.Button(string.Format("{0} ({1})", sd.asset.name, sd.slotName))) { if (UpdateSourceAsset(sd.asset)) { selectedRaceIndex = 0; } } } } } GUILayout.Space(20); if (source.TriangleCount > 0) { EditorGUILayout.LabelField("Triangle Indices Count: " + source.TriangleCount); EditorGUILayout.LabelField("Submesh Count: " + source.SubmeshCount); EditorGUILayout.LabelField("Hidden Triangle Count: " + source.HiddenCount); } else { EditorGUILayout.LabelField("No triangle array found"); } GUILayout.Space(20); if (!GeometrySelectorWindow.IsOpen) { EditorGUI.BeginDisabledGroup(source.asset == null); if (GUILayout.Button("Begin Editing", GUILayout.MinHeight(50))) { if (source.asset != null) { beginSceneEditing = true; } } EditorGUI.EndDisabledGroup(); GUILayout.Space(20); GUILayout.Label("Editing will be done in an empty scene."); GUILayout.Label("You will be prompted to save the scene"); GUILayout.Label("if there are any unsaved changes."); } serializedObject.ApplyModifiedProperties(); if (beginSceneEditing) { // This has to happen outside the inspector EditorApplication.delayCall += CreateSceneEditObject; } }
public override void OnInspectorGUI() { serializedObject.Update(); GUILayout.Label ("Avatar Name", EditorStyles.boldLabel); avatarName.stringValue = EditorGUILayout.TextArea(avatarName.stringValue); GUILayout.Space(20); GUILayout.BeginHorizontal(); if(GUILayout.Button("Save Avatar")){ UMASaveTool umaSaveTool = (UMASaveTool)target; GameObject gameObject = (GameObject)umaSaveTool.gameObject; UMADynamicAvatar umaDynamicAvatar = gameObject.GetComponent("UMADynamicAvatar") as UMADynamicAvatar; if(umaDynamicAvatar){ umaDynamicAvatar.SaveToMemoryStream(); var path = EditorUtility.SaveFilePanel("Save serialized Avatar","",avatarName.stringValue + ".txt","txt"); if(path.Length != 0) { System.IO.File.WriteAllText(path, umaDynamicAvatar.streamedUMA); } } } if(GUILayout.Button("Load Avatar")){ UMASaveTool umaSaveTool = (UMASaveTool)target; GameObject gameObject = (GameObject)umaSaveTool.gameObject; UMAData umaData = gameObject.GetComponent("UMAData") as UMAData; UMADynamicAvatar umaDynamicAvatar = gameObject.GetComponent("UMADynamicAvatar") as UMADynamicAvatar; RaceData umaRace = umaData.umaRecipe.raceData; if(umaData && umaDynamicAvatar){ var path = EditorUtility.OpenFilePanel("Load serialized Avatar","","txt"); if (path.Length != 0) { umaDynamicAvatar.streamedUMA = System.IO.File.ReadAllText(path); umaDynamicAvatar.LoadFromMemoryStream(); if(umaRace != umaData.umaRecipe.raceData){ //Different race, we need to create it Transform tempParent = umaData.transform.parent.parent; UMAData.UMARecipe umaRecipe = new UMAData.UMARecipe(); if(umaData.umaRecipe.raceData.raceName == "HumanMale"){ umaRecipe.raceData = umaDynamicAvatar.raceLibrary.raceDictionary["HumanMale"]; }else if(umaData.umaRecipe.raceData.raceName == "HumanFemale"){ umaRecipe.raceData = umaDynamicAvatar.raceLibrary.raceDictionary["HumanFemale"]; } Transform tempUMA = (Instantiate(umaRecipe.raceData.racePrefab ,umaData.transform.position,umaData.transform.rotation) as GameObject).transform; UMAData newUMA = tempUMA.gameObject.GetComponentInChildren<UMAData>(); newUMA.umaRecipe = umaRecipe; UMADynamicAvatar tempAvatar = newUMA.gameObject.AddComponent("UMADynamicAvatar") as UMADynamicAvatar; tempAvatar.Initialize(); newUMA.gameObject.AddComponent("UMASaveTool"); tempAvatar.streamedUMA = umaDynamicAvatar.streamedUMA; tempAvatar.umaPackRecipe = umaDynamicAvatar.umaPackRecipe; newUMA.umaRecipe = umaData.umaRecipe; newUMA.atlasResolutionScale = umaData.atlasResolutionScale; newUMA.Dirty(true, true, true); newUMA.transform.parent.gameObject.name = avatarName.stringValue; newUMA.transform.parent.transform.parent = tempParent; Destroy(umaData.transform.parent.gameObject); }else{ umaData.Dirty(true, true, true); } } } } GUILayout.EndHorizontal(); GUILayout.Space(20); serializedObject.ApplyModifiedProperties(); }
void GenerateOneUMA() { var umaRecipe = new UMAData.UMARecipe(); int randomResult = Random.Range(0, 2); // randomResult = 0; if(randomResult == 0) { umaRecipe.SetRace(raceLibrary.GetRace("HumanMale")); }else{ umaRecipe.SetRace(raceLibrary.GetRace("HumanFemale")); } tempUMA = (Instantiate(umaRecipe.raceData.racePrefab ,Vector3.zero,Quaternion.identity) as GameObject).transform; umaData = tempUMA.gameObject.GetComponentInChildren<UMAData>(); umaData.umaRecipe = umaRecipe; umaData.useLegacyCombiner = useLegacyCombiner; SetUMAData(); GenerateUMAShapes(); DefineSlots(); umaData.myRenderer.enabled = false; if(zeroPoint){ tempUMA.transform.position = new Vector3(zeroPoint.position.x,zeroPoint.position.y,zeroPoint.position.z); }else{ tempUMA.transform.position = new Vector3(0,0,0); } tempUMA.parent = transform; UMADynamicAvatar umaDynamicAvatar = umaData.gameObject.AddComponent("UMADynamicAvatar") as UMADynamicAvatar; umaDynamicAvatar.Initialize(); umaData.gameObject.AddComponent("UMASaveTool"); }
private void DoDimmingAndNeutralizing() { if (wardrobeRecipeToPhoto.Count > 0) { if (Debug.isDebugBuild) { Debug.Log("Doing Dimming And Neutralizing for " + wardrobeRecipeToPhoto[0].name); } } else { if (Debug.isDebugBuild) { Debug.Log("Doing Dimming And Neutralizing for Body shots"); } } int numAvatarSlots = avatarToPhoto.umaData.GetSlotArraySize(); originalColors.Clear(); List <string> slotsInRecipe = new List <string>(); List <string> overlaysInRecipe = new List <string>(); foreach (UMATextRecipe utr in wardrobeRecipeToPhoto) { UMAData.UMARecipe tempLoadedRecipe = new UMAData.UMARecipe(); utr.Load(tempLoadedRecipe, avatarToPhoto.context); foreach (SlotData slot in tempLoadedRecipe.slotDataList) { if (slot != null) { slotsInRecipe.Add(slot.asset.name); foreach (OverlayData wOverlay in slot.GetOverlayList()) { if (!overlaysInRecipe.Contains(wOverlay.asset.name)) { overlaysInRecipe.Add(wOverlay.asset.name); } } } } } //Deal with skin color first if we are dimming if (dimAllButTarget) { OverlayColorData[] sharedColors = avatarToPhoto.umaData.umaRecipe.sharedColors; for (int i = 0; i < sharedColors.Length; i++) { if (sharedColors[i].name == "Skin" || sharedColors[i].name == "skin") { sharedColors[i].color = dimToColor; if (sharedColors[i].channelAdditiveMask.Length >= 3) { sharedColors[i].channelAdditiveMask[2] = dimToMetallic; } } } } for (int i = 0; i < numAvatarSlots; i++) { if (avatarToPhoto.umaData.GetSlot(i) != null) { var overlaysInAvatarSlot = avatarToPhoto.umaData.GetSlot(i).GetOverlayList(); if (slotsInRecipe.Contains(avatarToPhoto.umaData.GetSlot(i).asset.name)) { if (neutralizeTargetColors || dimAllButTarget) { for (int ii = 0; ii < overlaysInAvatarSlot.Count; ii++) { //there is a problem here where if the recipe also contains replacement body slots (like my toon CapriPants_LEGS) these also get set to white //so we need to check if the overlay contains any body part names I think bool overlayIsBody = false; var thisOverlayName = overlaysInAvatarSlot[ii].asset.name; if (thisOverlayName.IndexOf("Face", StringComparison.OrdinalIgnoreCase) > -1 // || thisOverlayName.IndexOf("Torso", StringComparison.OrdinalIgnoreCase) > -1 || thisOverlayName.IndexOf("Arms", StringComparison.OrdinalIgnoreCase) > -1 || thisOverlayName.IndexOf("Hands", StringComparison.OrdinalIgnoreCase) > -1 || thisOverlayName.IndexOf("Legs", StringComparison.OrdinalIgnoreCase) > -1 || thisOverlayName.IndexOf("Feet", StringComparison.OrdinalIgnoreCase) > -1 || thisOverlayName.IndexOf("Body", StringComparison.OrdinalIgnoreCase) > -1) { overlayIsBody = true; } if (overlaysInRecipe.Contains(overlaysInAvatarSlot[ii].asset.name) && overlayIsBody == false) { if (!originalColors.ContainsKey(i)) { originalColors.Add(i, new Dictionary <int, Color>()); } if (!originalColors[i].ContainsKey(ii)) { originalColors[i].Add(ii, overlaysInAvatarSlot[ii].colorData.color); } overlaysInAvatarSlot[ii].colorData.color = neutralizeToColor; if (overlaysInAvatarSlot[ii].colorData.channelAdditiveMask.Length >= 3) { overlaysInAvatarSlot[ii].colorData.channelAdditiveMask[2] = neutralizeToMetallic; } } else { if (dimAllButTarget) { if (!originalColors.ContainsKey(i)) { originalColors.Add(i, new Dictionary <int, Color>()); } if (!originalColors[i].ContainsKey(ii)) { originalColors[i].Add(ii, overlaysInAvatarSlot[ii].colorData.color); } overlaysInAvatarSlot[ii].colorData.color = dimToColor; if (overlaysInAvatarSlot[ii].colorData.channelAdditiveMask.Length >= 3) { overlaysInAvatarSlot[ii].colorData.channelAdditiveMask[2] = dimToMetallic; } } } } } } else { if (dimAllButTarget) { for (int ii = 0; ii < overlaysInAvatarSlot.Count; ii++) { if (!overlaysInRecipe.Contains(overlaysInAvatarSlot[ii].asset.name)) { if (!originalColors.ContainsKey(i)) { originalColors.Add(i, new Dictionary <int, Color>()); } if (!originalColors[i].ContainsKey(ii)) { originalColors[i].Add(ii, overlaysInAvatarSlot[ii].colorData.color); } overlaysInAvatarSlot[ii].colorData.color = dimToColor; if (overlaysInAvatarSlot[ii].colorData.channelAdditiveMask.Length >= 3) { overlaysInAvatarSlot[ii].colorData.channelAdditiveMask[2] = dimToMetallic; } } } } } } } avatarToPhoto.umaData.dirty = false; avatarToPhoto.umaData.Dirty(false, true, false); }
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 IncludeRecipe(UMARecipeBase recipe, UMAData.UMARecipe umaRecipe, UMAContextBase context, bool dontSerialize) { UMAData.UMARecipe cachedRecipe = recipe.GetCachedRecipe(context); umaRecipe.Merge(cachedRecipe, dontSerialize); }