/// <summary> /// Removes a list of downloadingAssetItems from the downloadingItems List. /// </summary> /// <param name="assetName"></param> public IEnumerator RemoveDownload(List <DownloadingAssetItem> itemsToRemove) { //Not used any more UMAs check the status of stuff they asked for themselves //Dictionary<UMAAvatarBase, List<string>> updatedUMAs = new Dictionary<UMAAvatarBase, List<string>>(); foreach (DownloadingAssetItem item in itemsToRemove) { item.isBeingRemoved = true; } foreach (DownloadingAssetItem item in itemsToRemove) { string error = ""; //we need to check everyitem in this batch belongs to an asset bundle that has actually been loaded LoadedAssetBundle loadedBundleTest = AssetBundleManager.GetLoadedAssetBundle(item.containingBundle, out error); AssetBundle loadedBundleABTest = loadedBundleTest.m_AssetBundle; if (loadedBundleABTest == null && (String.IsNullOrEmpty(error))) { while (loadedBundleTest.m_AssetBundle == null) { //could say we are unpacking here yield return(null); } } if (!String.IsNullOrEmpty(error)) { Debug.LogError(error); yield break; } } //Now every item in the batch should be in a loaded bundle that is ready to use. foreach (DownloadingAssetItem item in itemsToRemove) { if (item != null) { string error = ""; var loadedBundle = AssetBundleManager.GetLoadedAssetBundle(item.containingBundle, out error); var loadedBundleAB = loadedBundle.m_AssetBundle; if (!String.IsNullOrEmpty(error)) { Debug.LogError(error); yield break; } var assetType = item.tempAsset.GetType(); //deal with RuntimeAnimatorController funkiness //the actual type of an instantiated clone of a RuntimeAnimatorController in the editor is UnityEditor.Animations.AnimatorController if (assetType.ToString().IndexOf("AnimatorController") > -1) { assetType = typeof(RuntimeAnimatorController); } var itemFilename = AssetBundleManager.AssetBundleIndexObject.GetFilenameFromAssetName(item.containingBundle, item.requiredAssetName, assetType.ToString()); if (assetType == typeof(RaceData)) { //HACK TO FIX RACEDATA DYNAMICDNACONVERTERS DYNAMICDNA ASSETS CAUSING LOAD FAILURES in UNITY 5.5+ //As of Unity 5.5 a bug has reappeared when loading some types of assets that reference assets in other bundles. //AssetBundleManager successfully ensures these required bundles are loaded first, but even so Unity fils to load //the required asset from them in some cases, notably it seems when the required asset is set in the field of a Prefab (like our DNAAssets are) //To fix this generally we could 'LoadAllAssets' from any dependent bundles, but this could incur significant memory overhead //So for now we will just fix this for UMA and hope a patch is forthcoming in a subsequent version of Unity if (AssetBundleManager.AssetBundleIndexObject.GetAllDependencies(item.containingBundle).Length > 0) { var allDeps = AssetBundleManager.AssetBundleIndexObject.GetAllDependencies(item.containingBundle); for (int i = 0; i < allDeps.Length; i++) { string depsError = ""; LoadedAssetBundle depsBundle = AssetBundleManager.GetLoadedAssetBundle(allDeps[i], out depsError); if (String.IsNullOrEmpty(depsError) && depsBundle != null) { depsBundle.m_AssetBundle.LoadAllAssets <DynamicUMADnaAsset>(); } } } RaceData actualRace = loadedBundleAB.LoadAsset <RaceData>(itemFilename); UMAContext.Instance.raceLibrary.AddRace(actualRace); UMAContext.Instance.raceLibrary.UpdateDictionary(); } else if (assetType == typeof(SlotDataAsset)) { SlotDataAsset thisSlot = null; thisSlot = loadedBundleAB.LoadAsset <SlotDataAsset>(itemFilename); if (thisSlot != null) { UMAContext.Instance.slotLibrary.AddSlotAsset(thisSlot); } else { Debug.LogWarning("[DynamicAssetLoader] could not add downloaded slot" + item.requiredAssetName); } } else if (assetType == typeof(OverlayDataAsset)) { OverlayDataAsset thisOverlay = null; thisOverlay = loadedBundleAB.LoadAsset <OverlayDataAsset>(itemFilename); if (thisOverlay != null) { UMAContext.Instance.overlayLibrary.AddOverlayAsset(thisOverlay); } else { Debug.LogWarning("[DynamicAssetLoader] could not add downloaded overlay" + item.requiredAssetName + " from assetbundle " + item.containingBundle); } } else if (assetType == typeof(UMATextRecipe)) { UMATextRecipe downloadedRecipe = loadedBundleAB.LoadAsset <UMATextRecipe>(itemFilename); (UMAContext.Instance.dynamicCharacterSystem as UMACharacterSystem.DynamicCharacterSystem).AddRecipe(downloadedRecipe); } else if (assetType == typeof(UMAWardrobeRecipe)) { UMAWardrobeRecipe downloadedRecipe = loadedBundleAB.LoadAsset <UMAWardrobeRecipe>(itemFilename); (UMAContext.Instance.dynamicCharacterSystem as UMACharacterSystem.DynamicCharacterSystem).AddRecipe(downloadedRecipe); } else if (item.dynamicCallback.Count > 0) { //get the asset as whatever the type of the tempAsset is //send this as an array to the dynamicCallback var downloadedAsset = loadedBundleAB.LoadAsset(itemFilename, assetType); var downloadedAssetArray = Array.CreateInstance(assetType, 1); downloadedAssetArray.SetValue(downloadedAsset, 0); for (int i = 0; i < item.dynamicCallback.Count; i++) { item.dynamicCallback[i].DynamicInvoke(downloadedAssetArray); } } if (!String.IsNullOrEmpty(error)) { Debug.LogError(error); } } downloadingItems.Remove(item); } if (downloadingItems.Count == 0) { areDownloadedItemsReady = true; //AssetBundleManager.UnloadAllAssetBundles();//we cant do this yet } //yield break; }
/// <summary> /// Removes a list of downloadingAssetItems from the downloadingItems List. /// </summary> /// <param name="assetName"></param> public IEnumerator RemoveDownload(List <DownloadingAssetItem> itemsToRemove) { //Not used any more UMAs check the status of stuff they asked for themselves //Dictionary<UMAAvatarBase, List<string>> updatedUMAs = new Dictionary<UMAAvatarBase, List<string>>(); foreach (DownloadingAssetItem item in itemsToRemove) { item.isBeingRemoved = true; } foreach (DownloadingAssetItem item in itemsToRemove) { string error = ""; //we need to check everyitem in this batch belongs to an asset bundle that has actually been loaded LoadedAssetBundle loadedBundleTest = AssetBundleManager.GetLoadedAssetBundle(item.containingBundle, out error); AssetBundle loadedBundleABTest = loadedBundleTest.m_AssetBundle; if (loadedBundleABTest == null && (String.IsNullOrEmpty(error))) { while (loadedBundleTest.m_AssetBundle == null) { //could say we are unpacking here yield return(null); } } if (!String.IsNullOrEmpty(error)) { Debug.LogError(error); yield break; } } //Now every item in the batch should be in a loaded bundle that is ready to use. foreach (DownloadingAssetItem item in itemsToRemove) { if (item != null) { string error = ""; var loadedBundle = AssetBundleManager.GetLoadedAssetBundle(item.containingBundle, out error); var loadedBundleAB = loadedBundle.m_AssetBundle; if (!String.IsNullOrEmpty(error)) { Debug.LogError(error); yield break; } var assetType = item.tempAsset.GetType(); //deal with RuntimeAnimatorController funkiness //the actual type of an instantiated clone of a RuntimeAnimatorController in the editor is UnityEditor.Animations.AnimatorController if (assetType.ToString().IndexOf("AnimatorController") > -1) { assetType = typeof(RuntimeAnimatorController); } var itemFilename = AssetBundleManager.AssetBundleIndexObject.GetFilenameFromAssetName(item.containingBundle, item.requiredAssetName, assetType.ToString()); if (assetType == typeof(RaceData)) { RaceData actualRace = loadedBundleAB.LoadAsset <RaceData>(itemFilename); UMAContext.Instance.raceLibrary.AddRace(actualRace); UMAContext.Instance.raceLibrary.UpdateDictionary(); } else if (assetType == typeof(SlotDataAsset)) { SlotDataAsset thisSlot = null; thisSlot = loadedBundleAB.LoadAsset <SlotDataAsset>(itemFilename); if (thisSlot != null) { UMAContext.Instance.slotLibrary.AddSlotAsset(thisSlot); } else { Debug.LogWarning("[DynamicAssetLoader] could not add downloaded slot" + item.requiredAssetName); } } else if (assetType == typeof(OverlayDataAsset)) { OverlayDataAsset thisOverlay = null; thisOverlay = loadedBundleAB.LoadAsset <OverlayDataAsset>(itemFilename); if (thisOverlay != null) { UMAContext.Instance.overlayLibrary.AddOverlayAsset(thisOverlay); } else { Debug.LogWarning("[DynamicAssetLoader] could not add downloaded overlay" + item.requiredAssetName + " from assetbundle " + item.containingBundle); } } else if (assetType == typeof(UMATextRecipe)) { UMATextRecipe downloadedRecipe = loadedBundleAB.LoadAsset <UMATextRecipe>(itemFilename); (UMAContext.Instance.dynamicCharacterSystem as UMACharacterSystem.DynamicCharacterSystem).AddRecipe(downloadedRecipe); } else if (assetType == typeof(UMAWardrobeRecipe)) { UMAWardrobeRecipe downloadedRecipe = loadedBundleAB.LoadAsset <UMAWardrobeRecipe>(itemFilename); (UMAContext.Instance.dynamicCharacterSystem as UMACharacterSystem.DynamicCharacterSystem).AddRecipe(downloadedRecipe); } else if (item.dynamicCallback.Count > 0) { //get the asset as whatever the type of the tempAsset is //send this as an array to the dynamicCallback var downloadedAsset = loadedBundleAB.LoadAsset(itemFilename, assetType); var downloadedAssetArray = Array.CreateInstance(assetType, 1); downloadedAssetArray.SetValue(downloadedAsset, 0); for (int i = 0; i < item.dynamicCallback.Count; i++) { item.dynamicCallback[i].DynamicInvoke(downloadedAssetArray); } } if (!String.IsNullOrEmpty(error)) { Debug.LogError(error); } } downloadingItems.Remove(item); } if (downloadingItems.Count == 0) { areDownloadedItemsReady = true; //AssetBundleManager.UnloadAllAssetBundles();//we cant do this yet } //yield break; }
/// <summary> /// Get all the UMATextRecipes/UMWardrobeRecipes /// </summary> /// <returns></returns> private List <AssetItem> GetAddressableRecipes() { List <AssetItem> theRecipes = new List <AssetItem>(); Type theType; //********************************************************************************************** //* Add Wardrobe Recipes //********************************************************************************************** theType = UMAAssetIndexer.Instance.GetIndexedType(typeof(UMAWardrobeRecipe)); var wardrobe = UMAAssetIndexer.Instance.GetAssetDictionary(theType).Values; foreach (AssetItem ai in wardrobe) { UMAWardrobeRecipe uwr = ai.Item as UMAWardrobeRecipe; if (uwr != null) { if (uwr.resourcesOnly) { var items = UMAAssetIndexer.Instance.GetAssetItems(uwr); foreach (AssetItem resourceItem in items) { resourceItem.IsResource = true; } continue; } theRecipes.Add(ai); } } theType = UMAAssetIndexer.Instance.GetIndexedType(typeof(UMATextRecipe)); var trecipes = UMAAssetIndexer.Instance.GetAssetDictionary(theType).Values; foreach (AssetItem ai in trecipes) { UMATextRecipe utr = ai.Item as UMATextRecipe; if (utr != null) { if (utr.resourcesOnly) { var items = UMAAssetIndexer.Instance.GetAssetItems(utr); foreach (AssetItem resourceItem in items) { resourceItem.IsResource = true; } continue; } theRecipes.Add(ai); } } theType = UMAAssetIndexer.Instance.GetIndexedType(typeof(UMAWardrobeCollection)); var wcrecipes = UMAAssetIndexer.Instance.GetAssetDictionary(theType).Values; foreach (AssetItem ai in wcrecipes) { UMATextRecipe utr = ai.Item as UMATextRecipe; if (utr != null) { if (utr.resourcesOnly) { var items = UMAAssetIndexer.Instance.GetAssetItems(utr); foreach (AssetItem resourceItem in items) { resourceItem.IsResource = true; } continue; } theRecipes.Add(ai); } } return(theRecipes); }