//Override Load from PackedRecipeBase /// <summary> /// Load this Recipe's recipeString into the specified UMAData.UMARecipe. If there is Wardrobe data in the recipe string, its values are set to this recipe assets 'activeWardrobeSet' field /// </summary> /// <param name="umaRecipe">UMA recipe.</param> /// <param name="context">Context.</param> public override void Load(UMA.UMAData.UMARecipe umaRecipe, UMAContextBase context = null) { //This check can be removed in future- If we set the recipeType properly from now on we should not need to do this check var typeInRecipe = GetRecipesType(recipeString); recipeType = typeInRecipe != "Standard" ? typeInRecipe : recipeType; if (RecipeHasWardrobeSet(recipeString)) { activeWardrobeSet = GetRecipesWardrobeSet(recipeString); } //if its an old UMARecipe there wont be an activeWardrobeSet field if (activeWardrobeSet == null) { recipeType = "Standard"; base.Load(umaRecipe, context); return; } //if it has a wardrobeSet or was saved using the DCSPackRecipe Model if (activeWardrobeSet.Count > 0 || (recipeType == "DynamicCharacterAvatar" /*|| recipeType == "WardrobeCollection"*/)) { var packedRecipe = PackedLoadDCSInternal(context /*, recipeString*/); UnpackRecipe(umaRecipe, packedRecipe, context); } else //we can use standard UMALoading { base.Load(umaRecipe, context); } }
/// <summary> /// Save data from the specified UMA recipe. /// </summary> /// <param name="umaRecipe">UMA recipe.</param> /// <param name="context">Context.</param> public override void Save(UMA.UMAData.UMARecipe umaRecipe, UMAContextBase context) { umaRecipe.MergeMatchingOverlays(); var packedRecipe = PackRecipeV3(umaRecipe); PackedSave(packedRecipe, context); }
//This is used when an inspected recipe asset is saved public override void Save(UMAData.UMARecipe umaRecipe, UMAContextBase 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 = PackRecipeV3(umaRecipe); //DCSPackRecipe doesn't do any more work, it just gets the values from PackRecipeV3 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 = PackRecipeV3(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); } }
/// <summary> /// Deserialize recipeString data into packed recipe. /// </summary> /// <returns>The packed recipe.</returns> /// <param name="context">Context.</param> public override UMAPackedRecipeBase.UMAPackRecipe PackedLoad(UMAContextBase context = null) { if ((recipeString == null) || (recipeString.Length == 0)) { return(new UMAPackRecipe()); } return(JsonUtility.FromJson <UMAPackRecipe>(recipeString)); }
public void Initialize() { if (context == null) { context = UMAContextBase.Instance; } if (umaData == null) { umaData = GetComponent <UMAData>(); if (umaData == null) { umaData = gameObject.AddComponent <UMAData>(); umaData.umaRecipe = new UMAData.UMARecipe(); // TEST JRRM if (umaGenerator != null && !umaGenerator.gameObject.activeInHierarchy) { if (Debug.isDebugBuild) { Debug.LogError("Invalid UMA Generator on Avatar.", gameObject); Debug.LogError("UMA generators must be active scene objects!", umaGenerator.gameObject); } umaGenerator = null; } } } if (umaGenerator != null) { umaData.umaGenerator = umaGenerator; } if (CharacterCreated != null) { umaData.CharacterCreated = CharacterCreated; } if (CharacterBegun != null) { umaData.CharacterBegun = CharacterBegun; } if (CharacterDestroyed != null) { umaData.CharacterDestroyed = CharacterDestroyed; } if (CharacterUpdated != null) { umaData.CharacterUpdated = CharacterUpdated; } if (CharacterDnaUpdated != null) { umaData.CharacterDnaUpdated = CharacterDnaUpdated; } if (AnimatorStateSaved != null) { umaData.AnimatorStateSaved = AnimatorStateSaved; } if (AnimatorStateRestored != null) { umaData.AnimatorStateRestored = AnimatorStateRestored; } }
static void CreateDynamicAvatarMenuItem() { var res = new GameObject("New Dynamic Avatar"); var da = res.AddComponent <UMADynamicAvatar>(); da.context = UMAContextBase.FindInstance(); da.umaGenerator = Component.FindObjectOfType <UMAGeneratorBase>(); UnityEditor.Selection.activeGameObject = res; }
//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, UMAContextBase context, Dictionary <string, UMATextRecipe> wardrobeRecipes, bool backwardsCompatible = true) { if (wardrobeRecipes.Count > 0) { activeWardrobeSet = GenerateWardrobeSet(wardrobeRecipes); } recipeType = backwardsCompatible ? "Standard" : "DynamicCharacterAvatar"; Save(umaRecipe, context); }
#pragma warning restore 618 /// <summary> /// Finds the singleton context in the scene. /// </summary> /// <returns>The UMA context.</returns> public static UMAContextBase FindInstance() { if (Instance == null) { var contextGO = GameObject.Find("UMAContext"); if (contextGO != null) { Instance = contextGO.GetComponent <UMAContextBase>(); } } if (Instance == null) { Instance = Component.FindObjectOfType <UMAContextBase>(); } return(Instance); }
/// <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(UMAContextBase context) { if (!cached || umaRecipe == null) { umaRecipe = new UMAData.UMARecipe(); Load(umaRecipe, context); #if !UNITY_EDITOR #if UMA_ADDRESSABLES // don't cache addressables, as they can be unloaded. cached = false; #else // do not cache in the editor cached = true; #endif #endif } return(umaRecipe); }
/// <summary> /// Returns the recipe string as a DCSUniversalPackRecipe data model that can be used by any UMA /// </summary> /// <param name="context"></param> /// <param name="recipeToUnpack"></param> /// <param name="targetUTR">If set the wardrobeSet (if it exists) and the recipeType will assigned to UMATextRecipe assets fields (used by the Recipe Editor)</param> /// <returns></returns> public static DCSUniversalPackRecipe PackedLoadDCS(UMAContextBase context, string recipeToUnpack, UMATextRecipe targetUTR = null) { if ((recipeToUnpack == null) || (recipeToUnpack.Length == 0)) { return(new DCSUniversalPackRecipe()); } //first use the DCSRecipeChecker to check if this is a DCS recipe var typeInRecipe = GetRecipesType(recipeToUnpack); var targetRecipeType = typeInRecipe != "Standard" ? typeInRecipe : (targetUTR != null ? targetUTR.recipeType : "Standard"); if (targetUTR != null) { targetUTR.recipeType = targetRecipeType; if (RecipeHasWardrobeSet(recipeToUnpack)) { targetUTR.activeWardrobeSet = GetRecipesWardrobeSet(recipeToUnpack); } } //Right now the only recipeType that uses the DCSModel is "DynamicCharacterAvatar" DCSUniversalPackRecipe thisUnpackedUniversal = null; if (targetRecipeType == "DynamicCharacterAvatar" || targetRecipeType == "WardrobeCollection") { var thisUnpacked = JsonUtility.FromJson <DCSPackRecipe>(recipeToUnpack); thisUnpackedUniversal = new DCSUniversalPackRecipe(thisUnpacked); } else { var thisUnpacked = JsonUtility.FromJson <UMAPackRecipe>(recipeToUnpack); thisUnpackedUniversal = new DCSUniversalPackRecipe(thisUnpacked); } if (RecipeHasWardrobeSet(recipeToUnpack)) { thisUnpackedUniversal.wardrobeSet = GetRecipesWardrobeSet(recipeToUnpack); } return(thisUnpackedUniversal); }
public virtual void AddToContext(UMAContextBase context) { if (context == null) { return; } if (overlayData.Length > 0) { #if UNITY_EDITOR UnityEditor.Undo.RecordObject(context, "Added overlays from asset collection"); #endif for (int i = 0; i < overlayData.Length; i++) { context.AddOverlayAsset(overlayData[i]); } } if (slotData.Length > 0) { #if UNITY_EDITOR UnityEditor.Undo.RecordObject(context, "Added slots from asset collection"); #endif for (int i = 0; i < slotData.Length; i++) { context.AddSlotAsset(slotData[i]); } } if (raceData.Length > 0) { #if UNITY_EDITOR UnityEditor.Undo.RecordObject(context, "Added races from asset collection"); #endif for (int i = 0; i < raceData.Length; i++) { context.AddRace(raceData[i]); } } }
/// <summary> /// Serialize the packed recipe. /// </summary> /// <param name="packedRecipe">Packed recipe.</param> /// <param name="context">Context.</param> public abstract void PackedSave(UMAPackRecipe packedRecipe, UMAContextBase context);
/// <summary> /// Load serialized data into the packed recipe. /// </summary> /// <returns>The UMAPackRecipe.</returns> /// <param name="context">Context.</param> public abstract UMAPackRecipe PackedLoad(UMAContextBase context);
public static bool UnpackRecipeVersion1(UMA.UMAData.UMARecipe umaRecipe, UMAPackRecipe umaPackRecipe, UMAContextBase context) { if (!UMAPackRecipe.ArrayHasData(umaPackRecipe.packedSlotDataList)) { return(false); } umaRecipe.slotDataList = new SlotData[umaPackRecipe.packedSlotDataList.Length]; umaRecipe.SetRace(context.GetRace(umaPackRecipe.race)); umaRecipe.ClearDna(); for (int dna = 0; dna < umaPackRecipe.packedDna.Count; dna++) { Type dnaType = UMADna.GetType(umaPackRecipe.packedDna[dna].dnaType); umaRecipe.AddDna(UMADna.LoadInstance(dnaType, umaPackRecipe.packedDna[dna].packedDna)); } for (int i = 0; i < umaPackRecipe.packedSlotDataList.Length; i++) { if (UMAPackRecipe.SlotIsValid(umaPackRecipe.packedSlotDataList[i])) { var tempSlotData = context.InstantiateSlot(umaPackRecipe.packedSlotDataList[i].slotID); tempSlotData.overlayScale = umaPackRecipe.packedSlotDataList[i].overlayScale * 0.01f; umaRecipe.slotDataList[i] = tempSlotData; if (umaPackRecipe.packedSlotDataList[i].copyOverlayIndex == -1) { for (int overlay = 0; overlay < umaPackRecipe.packedSlotDataList[i].OverlayDataList.Length; overlay++) { Color tempColor; Rect tempRect; if (UMAPackRecipe.ArrayHasData(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].colorList)) { tempColor = new Color(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].colorList[0] / 255.0f, umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].colorList[1] / 255.0f, umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].colorList[2] / 255.0f, umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].colorList[3] / 255.0f); } else { tempColor = new Color(1.0f, 1.0f, 1.0f, 1.0f); } if (UMAPackRecipe.ArrayHasData(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].rectList)) { Rect originalRect = context.InstantiateOverlay(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].overlayID).rect; tempRect = new Rect(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].rectList[0], umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].rectList[1], umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].rectList[2], umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].rectList[3]); Vector2 aspectRatio = new Vector2(tempRect.width / originalRect.width, tempRect.height / originalRect.height); tempRect = new Rect(tempRect.x / aspectRatio.x, tempRect.y / aspectRatio.y, tempRect.width / aspectRatio.x, tempRect.height / aspectRatio.y); } else { tempRect = new Rect(0, 0, 0, 0); } tempSlotData.AddOverlay(context.InstantiateOverlay(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].overlayID)); tempSlotData.GetOverlay(tempSlotData.OverlayCount - 1).colorData.color = tempColor; tempSlotData.GetOverlay(tempSlotData.OverlayCount - 1).rect = tempRect; if (UMAPackRecipe.ArrayHasData(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].channelMaskList)) { for (int channelAdjust = 0; channelAdjust < umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].channelMaskList.Length; channelAdjust++) { packedOverlayData tempData = umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay]; tempSlotData.GetOverlay(tempSlotData.OverlayCount - 1).SetColor(channelAdjust, new Color32((byte)tempData.channelMaskList[channelAdjust][0], (byte)tempData.channelMaskList[channelAdjust][1], (byte)tempData.channelMaskList[channelAdjust][2], (byte)tempData.channelMaskList[channelAdjust][3])); } } if (UMAPackRecipe.ArrayHasData(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].channelAdditiveMaskList)) { for (int channelAdjust = 0; channelAdjust < umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].channelAdditiveMaskList.Length; channelAdjust++) { packedOverlayData tempData = umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay]; tempSlotData.GetOverlay(tempSlotData.OverlayCount - 1).SetAdditive(channelAdjust, new Color32((byte)tempData.channelAdditiveMaskList[channelAdjust][0], (byte)tempData.channelAdditiveMaskList[channelAdjust][1], (byte)tempData.channelAdditiveMaskList[channelAdjust][2], (byte)tempData.channelAdditiveMaskList[channelAdjust][3])); } } } } else { tempSlotData.SetOverlayList(umaRecipe.slotDataList[umaPackRecipe.packedSlotDataList[i].copyOverlayIndex].GetOverlayList()); } } } return(true); }
public static void UnpackRecipe(UMA.UMAData.UMARecipe umaRecipe, UMAPackRecipe umaPackRecipe, UMAContextBase context) { switch (umaPackRecipe.version) { case 3: UnpackRecipeVersion3(umaRecipe, umaPackRecipe, context); break; case 2: UnpackRecipeVersion2(umaRecipe, umaPackRecipe, context); break; case 1: default: if (UnpackRecipeVersion1(umaRecipe, umaPackRecipe, context)) { umaRecipe.MergeMatchingOverlays(); } break; } }
public static GameObject CreateEditorContext() { GameObject EditorUMAContextBase = null; if (UnityEditor.BuildPipeline.isBuildingPlayer) { return(null); } if (Application.isPlaying) { if (Debug.isDebugBuild) { Debug.LogWarning("There was no UMAContext in this scene. Please add the UMA_DCS prefab to this scene before you try to generate an UMA."); } return(null); } if (Debug.isDebugBuild) { Debug.Log("UMA Recipe Editor created an UMAEditorContext to enable editing. This will auto delete once you have finished editing your recipe or you add the UMA_DCS prefab to this scene."); } //if there is already an EditorUMAContextBase use it if (UMAContextBase.FindInstance() != null) { if (UMAContextBase.FindInstance().gameObject.name == "UMAEditorContext") { EditorUMAContextBase = UMAContextBase.FindInstance().gameObject; //if the UMAContextBase itself is on this game object, it means this was created and not deleted by the previous version of 'CreateEditorContext' //(The new version creates the UMAContextBase on a child game object called 'UMAContextBase' so that UMAContextBase.FindInstance can find it properly) //so in this case delete all the components that would have been added from the found gameObject from the previous code if (EditorUMAContextBase.GetComponent <UMAContextBase>()) { UMAUtils.DestroySceneObject(EditorUMAContextBase.GetComponent <UMAContextBase>()); //should also make the instance null again } } else if (UMAContextBase.FindInstance().gameObject.transform.parent.gameObject.name == "UMAEditorContext") { EditorUMAContextBase = UMAContextBase.FindInstance().gameObject.transform.parent.gameObject; } } else if (GameObject.Find("UMAEditorContext")) { EditorUMAContextBase = GameObject.Find("UMAEditorContext"); } else { EditorUMAContextBase = new GameObject(); EditorUMAContextBase.name = "UMAEditorContext"; } //Make this GameObject not show up in the scene or save EditorUMAContextBase.hideFlags = HideFlags.DontSave | HideFlags.NotEditable; //if this gameobject does not contain an UMAContextBase add it - we have to call it UMAContextBase because UMAContextBase.FindInstance searches for that game object var thisUMAContextBase = UMAContextBase.Instance = EditorUMAContextBase.GetComponentInChildren <UMAContextBase>(); if (UMAContextBase.Instance == null) { var thisUMAContextBaseGO = new GameObject(); thisUMAContextBaseGO.name = "UMAContext"; thisUMAContextBaseGO.transform.parent = EditorUMAContextBase.transform; thisUMAContextBase = thisUMAContextBaseGO.AddComponent <UMAGlobalContext>(); UMAContextBase.Instance = thisUMAContextBase; } return(EditorUMAContextBase); }
private void GenerateLookups(UMAContextBase context, List <AssetItem> wardrobe) { float pos = 0.0f; float inc = 1.0f / wardrobe.Count; // Get the slots, overlays, textures. // calculate the number of references for each of them. // Map the usage foreach (AssetItem recipeItem in wardrobe) { UMATextRecipe uwr = recipeItem.Item as UMATextRecipe; int iPos = Mathf.CeilToInt(pos); EditorUtility.DisplayProgressBar("Generating", "Calculating Usage: " + uwr.name, iPos); // todo: cache this UMAData.UMARecipe ur = UMAAssetIndexer.Instance.GetRecipe(uwr, context); if (ur.slotDataList == null) { continue; } foreach (SlotData sd in ur.slotDataList) { if (sd == null) { continue; } AssetItem ai = UMAAssetIndexer.Instance.GetAssetItem <SlotDataAsset>(sd.slotName); if (ai != null && ai.IsAlwaysLoaded == false) { // is this a utility slot? if so, we need to not delete it as an orphan. if (sd.asset.isUtilitySlot) { ai.IsAlwaysLoaded = true; } } //if (!(ai != null && ai.IsAlwaysLoaded)) //{ //AddToTracker = false; //} //else //{ int slotInstance = sd.asset.GetInstanceID(); if (!SlotTracker.ContainsKey(slotInstance)) { ai.IsAddressable = true; SlotTracker.Add(slotInstance, new List <UMATextRecipe>()); } SlotTracker[slotInstance].Add(uwr); if (!AddressLookup.ContainsKey(slotInstance)) { AddressLookup.Add(slotInstance, "Slt-" + sd.slotName); } //} List <OverlayData> odList = sd.GetOverlayList(); foreach (OverlayData od in odList) { if (od == null) { continue; } /* = GetAssetItem<OverlayDataAsset>(od.overlayName); * * if (ai != null && ai.IsAlwaysLoaded) * { * continue; * }*/ int OverlayInstance = od.asset.GetInstanceID(); if (!OverlayTracker.ContainsKey(OverlayInstance)) { OverlayTracker.Add(OverlayInstance, new List <UMATextRecipe>()); } OverlayTracker[OverlayInstance].Add(uwr); if (!AddressLookup.ContainsKey(OverlayInstance)) { ai.IsAddressable = true; AddressLookup.Add(OverlayInstance, "Ovl-" + od.overlayName); } foreach (Texture tx in od.textureArray) { if (tx == null) { continue; } int TextureID = tx.GetInstanceID(); if (!TextureTracker.ContainsKey(TextureID)) { TextureTracker.Add(TextureID, new List <UMATextRecipe>()); } TextureTracker[TextureID].Add(uwr); if (!AddressLookup.ContainsKey(TextureID)) { AddressLookup.Add(TextureID, "Tex-" + tx.name); } } } } pos += inc; } }
/// <summary> /// Load data into the specified UMA recipe. /// </summary> /// <param name="umaRecipe">UMA recipe.</param> /// <param name="context">Context.</param> public override void Load(UMA.UMAData.UMARecipe umaRecipe, UMAContextBase context) { var packedRecipe = PackedLoad(context); UnpackRecipe(umaRecipe, packedRecipe, context); }
public static GameObject CreateEditorContext() { GameObject EditorUMAContextBase = null; if (UnityEditor.BuildPipeline.isBuildingPlayer) { return(null); } if (Application.isPlaying) { if (Debug.isDebugBuild) { Debug.LogWarning("There was no UMAContext in this scene. Please add the UMA context prefab to this scene before you try to generate an UMA."); } return(null); } if (Debug.isDebugBuild) { Debug.Log("UMA Recipe Editor created an UMAEditorContext to enable editing. This will auto delete once you have finished editing your recipe or you add a UMA prefab with a context to this scene."); } //if there is already an EditorUMAContextBase use it if (UMAContextBase.FindInstance() != null) { if (UMAContextBase.FindInstance().gameObject.name == "UMAEditorContext") { EditorUMAContextBase = UMAContextBase.FindInstance().gameObject; //if the UMAContextBase itself is on this game object, it means this was created and not deleted by the previous version of 'CreateEditorContext' //(The new version creates the UMAContextBase on a child game object called 'UMAContextBase' so that UMAContextBase.FindInstance can find it properly) //so in this case delete all the components that would have been added from the found gameObject from the previous code if (EditorUMAContextBase.GetComponent <UMAContextBase>()) { UMAUtils.DestroySceneObject(EditorUMAContextBase.GetComponent <UMAContextBase>()); //should also make the instance null again } } else if (UMAContextBase.FindInstance().gameObject.transform.parent.gameObject.name == "UMAEditorContext") { EditorUMAContextBase = UMAContextBase.FindInstance().gameObject.transform.parent.gameObject; } } else if (GameObject.Find("UMAEditorContext")) { EditorUMAContextBase = GameObject.Find("UMAEditorContext"); } else { EditorUMAContextBase = new GameObject(); EditorUMAContextBase.name = "UMAEditorContext"; } //Make this GameObject not show up in the scene or save EditorUMAContextBase.hideFlags = HideFlags.DontSave | HideFlags.NotEditable; //if this gameobject does not contain an UMAContextBase add it - we have to call it UMAContextBase because UMAContextBase.FindInstance searches for that game object var context = UMAContextBase.Instance = EditorUMAContextBase.GetComponentInChildren <UMAContextBase>(); if (UMAContextBase.Instance == null) { var GO = new GameObject(); GO.name = "UMAContext"; GO.transform.parent = EditorUMAContextBase.transform; context = GO.AddComponent <UMAGlobalContext>(); GO.AddComponent <UMADefaultMeshCombiner>(); var gen = GO.AddComponent <UMAGenerator>(); gen.fitAtlas = true; gen.SharperFitTextures = true; gen.AtlasOverflowFitMethod = UMAGeneratorBase.FitMethod.BestFitSquare; gen.convertRenderTexture = false; gen.editorAtlasResolution = 1024; gen.InitialScaleFactor = 2; gen.collectGarbage = false; gen.IterationCount = 1; gen.fastGeneration = true; gen.processAllPending = false; gen.NoCoroutines = true; UMAContextBase.Instance = context; } return(EditorUMAContextBase); }
public void GenerateAddressables() { try { //********************************************************************************************** //* Clear out the old data //********************************************************************************************** SlotTracker = new Dictionary <int, List <UMATextRecipe> >(); OverlayTracker = new Dictionary <int, List <UMATextRecipe> >(); TextureTracker = new Dictionary <int, List <UMATextRecipe> >(); GroupTracker = new Dictionary <int, AddressableAssetGroup>(); ClearAddressableFlags(typeof(SlotDataAsset)); ClearAddressableFlags(typeof(OverlayDataAsset)); // Will generate an editor context if needed. UMAContextBase context = UMAAssetIndexer.Instance.GetContext(); // Create the shared group that has each item packed separately. AddressableAssetGroup sharedGroup = AddressableUtility.AddressableSettings.CreateGroup(SharedGroupName, false, false, true, AddressableUtility.AddressableSettings.DefaultGroup.Schemas); sharedGroup.GetSchema <BundledAssetGroupSchema>().BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately; List <UMATextRecipe> theRecipes = new List <UMATextRecipe>(); //********************************************************************************************** //* Add Races //********************************************************************************************** System.Type theType = UMAAssetIndexer.Instance.GetIndexedType(typeof(RaceData)); var races = UMAAssetIndexer.Instance.GetAssetDictionary(theType).Values; foreach (AssetItem ai in races) { RaceData race = ai.Item as RaceData; if (race == null) { Debug.Log("Invalid race found!"); continue; } if (race.baseRaceRecipe as UMATextRecipe == null) { Debug.Log("Invalid base race recipe on race: " + race.raceName); } theRecipes.Add(race.baseRaceRecipe as UMATextRecipe); if (ai.IsAlwaysLoaded) { AssetItem recipe = UMAAssetIndexer.Instance.GetAssetItem <UMATextRecipe>(race.baseRaceRecipe.name); recipe.IsAlwaysLoaded = true; List <AssetItem> recipeItems = UMAAssetIndexer.Instance.GetAssetItems(race.baseRaceRecipe as UMAPackedRecipeBase, true); foreach (AssetItem recipeitem in recipeItems) { recipeitem.IsAlwaysLoaded = true; } } } var theRecipeItems = GetAddressableRecipes(); GenerateCollectionLabels(); GenerateLookups(context, theRecipeItems); float pos = 0.0f; float inc = 1.0f / theRecipes.Count; const string tprefix = "UTR_"; const string wprefix = "UWR_"; // Create the Addressable groups foreach (AssetItem recipeItem in theRecipeItems) { UMATextRecipe uwr = recipeItem.Item as UMATextRecipe; int iPos = Mathf.CeilToInt(pos); EditorUtility.DisplayProgressBar("Generating", "Creating Group: " + uwr.name, iPos); Debug.Log("Generating group: " + uwr.name); string groupName; if (uwr is UMAWardrobeRecipe) { groupName = wprefix + uwr.name; } else { groupName = tprefix + uwr.name; } AddressableAssetGroup recipeGroup = AddressableUtility.AddressableSettings.CreateGroup(groupName, false, false, true, AddressableUtility.AddressableSettings.DefaultGroup.Schemas); recipeGroup.GetSchema <BundledAssetGroupSchema>().BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether; if (GroupTracker.ContainsKey(uwr.GetInstanceID())) { Debug.Log("Group already exists????? " + uwr.name); continue; } GroupTracker.Add(uwr.GetInstanceID(), recipeGroup); pos += inc; } AddAddressableAssets(SlotTracker, sharedGroup); AddAddressableAssets(OverlayTracker, sharedGroup); AddAddressableAssets(TextureTracker, sharedGroup); AssignAddressableInformation(); ReleaseReferences(UMAAssetIndexer.Instance.GetIndexedType(typeof(SlotDataAsset))); ReleaseReferences(UMAAssetIndexer.Instance.GetIndexedType(typeof(OverlayDataAsset))); CleanupAddressables(true); } finally { EditorUtility.ClearProgressBar(); UMAAssetIndexer.Instance.DestroyEditorUMAContextBase(); UMAAssetIndexer.Instance.ForceSave(); } }
/// <summary> /// Serialize recipeString data into packed recipe. /// </summary> /// <param name="packedRecipe">Packed recipe.</param> /// <param name="context">Context.</param> public override void PackedSave(UMAPackedRecipeBase.UMAPackRecipe packedRecipe, UMAContextBase context) { recipeString = JsonUtility.ToJson(packedRecipe); }
/// <summary> /// Creates a temporary UMAContextBase for use when editing recipes when the open Scene does not have an UMAContextBase or libraries set up /// </summary> /// public override UMAContextBase CreateEditorContext() { UMAContextBase.CreateEditorContext(); return(UMAContextBase.Instance); }
/// <summary> /// Internal call to static PackedLoadDCS which uses the assets string and object and returns a DCSUniversalPackRecipe data model that can be used by any UMA /// </summary> /// <param name="context"></param> /// <returns></returns> protected DCSUniversalPackRecipe PackedLoadDCSInternal(UMAContextBase context /*, string recipeToUnpack*/) { return(PackedLoadDCS(context, recipeString, this)); }