internal static string GetAssetProviderName(AddressableAssetGroup group) { return(group.GetSchema <BundledAssetGroupSchema>().GetAssetCachedProviderId()); }
void PostProcessBundles(AddressableAssetGroup assetGroup, List <string> buildBundles, List <string> outputBundles, IBundleBuildResults buildResult, IWriteData writeData, ResourceManagerRuntimeData runtimeData, List <ContentCatalogDataEntry> locations, FileRegistry registry) { var schema = assetGroup.GetSchema <BundledAssetGroupSchema>(); if (schema == null) { return; } var path = schema.BuildPath.GetValue(assetGroup.Settings); if (string.IsNullOrEmpty(path)) { return; } for (int i = 0; i < buildBundles.Count; ++i) { var info = buildResult.BundleInfos[buildBundles[i]]; ContentCatalogDataEntry dataEntry = locations.FirstOrDefault(s => buildBundles[i] == (string)s.Keys[0]); if (dataEntry != null) { var requestOptions = new AssetBundleRequestOptions { Crc = schema.UseAssetBundleCrc ? info.Crc : 0, Hash = schema.UseAssetBundleCache ? info.Hash.ToString() : "", ChunkedTransfer = schema.ChunkedTransfer, RedirectLimit = schema.RedirectLimit, RetryCount = schema.RetryCount, Timeout = schema.Timeout, BundleName = Path.GetFileName(info.FileName), BundleSize = GetFileSize(info.FileName) }; dataEntry.Data = requestOptions; int extensionLength = Path.GetExtension(outputBundles[i]).Length; string[] deconstructedBundleName = outputBundles[i].Substring(0, outputBundles[i].Length - extensionLength).Split('_'); string reconstructedBundleName = string.Join("_", deconstructedBundleName, 1, deconstructedBundleName.Length - 1) + ".bundle"; outputBundles[i] = ConstructAssetBundleName(assetGroup, schema, info, reconstructedBundleName); dataEntry.InternalId = dataEntry.InternalId.Remove(dataEntry.InternalId.Length - buildBundles[i].Length) + outputBundles[i]; dataEntry.Keys[0] = outputBundles[i]; ReplaceDependencyKeys(buildBundles[i], outputBundles[i], locations); if (dataEntry.InternalId.StartsWith("http:\\")) { dataEntry.InternalId = dataEntry.InternalId.Replace("http:\\", "http://").Replace("\\", "/"); } if (dataEntry.InternalId.StartsWith("https:\\")) { dataEntry.InternalId = dataEntry.InternalId.Replace("https:\\", "https://").Replace("\\", "/"); } } else { Debug.LogWarningFormat("Unable to find ContentCatalogDataEntry for bundle {0}.", outputBundles[i]); } var targetPath = Path.Combine(path, outputBundles[i]); if (!Directory.Exists(Path.GetDirectoryName(targetPath))) { Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); } File.Copy(Path.Combine(assetGroup.Settings.buildSettings.bundleBuildPath, buildBundles[i]), targetPath, true); registry.AddFile(targetPath); } }
/// <inheritdoc /> protected override string ProcessGroup(AddressableAssetGroup assetGroup, AddressableAssetsBuildContext aaContext) { var errorString = string.Empty; PlayerDataGroupSchema playerSchema = assetGroup.GetSchema <PlayerDataGroupSchema>(); if (playerSchema != null) { if (CreateLocationsForPlayerData(playerSchema, assetGroup, aaContext.locations, aaContext.providerTypes)) { if (!m_CreatedProviderIds.ContainsKey(typeof(LegacyResourcesProvider).Name)) { m_CreatedProviderIds.Add(typeof(LegacyResourcesProvider).Name, null); m_ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData(typeof(LegacyResourcesProvider))); } } return(errorString); } var schema = assetGroup.GetSchema <BundledAssetGroupSchema>(); if (schema == null) { return(errorString); } var bundledProviderId = schema.GetBundleCachedProviderId(); var assetProviderId = schema.GetAssetCachedProviderId(); if (!m_CreatedProviderIds.ContainsKey(bundledProviderId)) { //TODO: pull from schema instead of ProjectConfigData var virtualBundleRuntimeData = new VirtualAssetBundleRuntimeData(ProjectConfigData.LocalLoadSpeed, ProjectConfigData.RemoteLoadSpeed); //save virtual runtime data to collect assets into virtual bundles m_CreatedProviderIds.Add(bundledProviderId, virtualBundleRuntimeData); } if (!m_CreatedProviderIds.ContainsKey(assetProviderId)) { m_CreatedProviderIds.Add(assetProviderId, null); var assetProviderData = ObjectInitializationData.CreateSerializedInitializationData <VirtualBundledAssetProvider>(assetProviderId); m_ResourceProviderData.Add(assetProviderData); } var bundleInputDefs = new List <AssetBundleBuild>(); List <AddressableAssetEntry> list = BuildScriptPackedMode.PrepGroupBundlePacking(assetGroup, bundleInputDefs, schema); aaContext.assetEntries.AddRange(list); for (int i = 0; i < bundleInputDefs.Count; i++) { if (aaContext.bundleToAssetGroup.ContainsKey(bundleInputDefs[i].assetBundleName)) { var bid = bundleInputDefs[i]; int count = 1; var newName = bid.assetBundleName; while (aaContext.bundleToAssetGroup.ContainsKey(newName) && count < 1000) { newName = bid.assetBundleName.Replace(".bundle", string.Format("{0}.bundle", count++)); } bundleInputDefs[i] = new AssetBundleBuild { assetBundleName = newName, addressableNames = bid.addressableNames, assetBundleVariant = bid.assetBundleVariant, assetNames = bid.assetNames }; } aaContext.bundleToAssetGroup.Add(bundleInputDefs[i].assetBundleName, assetGroup.Guid); } m_AllBundleInputDefinitions.AddRange(bundleInputDefs); return(errorString); }
internal static List <AssetEntryRevertOperation> DetermineRequiredAssetEntryUpdates(AddressableAssetGroup group, ContentUpdateScript.ContentUpdateContext contentUpdateContext) { if (!group.HasSchema <BundledAssetGroupSchema>()) { return(new List <AssetEntryRevertOperation>()); } bool groupIsStaticContentGroup = group.HasSchema <ContentUpdateGroupSchema>() && group.GetSchema <ContentUpdateGroupSchema>().StaticContent; List <AssetEntryRevertOperation> operations = new List <AssetEntryRevertOperation>(); foreach (AddressableAssetEntry entry in group.entries) { GUID guid = new GUID(entry.guid); if (!contentUpdateContext.WriteData.AssetToFiles.ContainsKey(guid)) { continue; } string file = contentUpdateContext.WriteData.AssetToFiles[guid][0]; string fullInternalBundleName = contentUpdateContext.WriteData.FileToBundle[file]; string finalBundleWritePath = contentUpdateContext.BundleToInternalBundleIdMap[fullInternalBundleName]; //Ensure we can get the catalog entry for the bundle we're looking to replace if (!contentUpdateContext.IdToCatalogDataEntryMap.TryGetValue(finalBundleWritePath, out ContentCatalogDataEntry catalogBundleEntry)) { continue; } //If new entries are added post initial build this will ensure that those new entries have their bundleFileId for SaveContentState entry.BundleFileId = catalogBundleEntry.InternalId; //If we have no cached state no reason to proceed. This is new to the build. if (!contentUpdateContext.GuidToPreviousAssetStateMap.TryGetValue(entry.guid, out CachedAssetState previousAssetState)) { continue; } //If the parent group is different we don't want to revert it to its previous state if (entry.parentGroup.Guid != previousAssetState.groupGuid) { continue; } //If the asset hash has changed and the group is not a static content update group we don't want to revert it to its previous state if (AssetDatabase.GetAssetDependencyHash(entry.AssetPath) != previousAssetState.asset.hash && !groupIsStaticContentGroup) { continue; } //If the previous asset state has the same bundle file id as the current build we don't want to revert it to its previous state if (catalogBundleEntry.InternalId == previousAssetState.bundleFileId) { continue; } var schema = group.GetSchema <BundledAssetGroupSchema>(); string loadPath = schema.LoadPath.GetValue(group.Settings); string buildPath = schema.BuildPath.GetValue(group.Settings); //Need to check and make sure our cached version exists if (string.IsNullOrEmpty(previousAssetState.bundleFileId)) { //Logging this as an error because a CachedAssetState without a set bundleFileId is indicative of a significant issue with the build script. Addressables.LogError($"CachedAssetState found for {entry.AssetPath} but the bundleFileId was never set on the previous build."); continue; } string previousBundlePath = previousAssetState.bundleFileId?.Replace(loadPath, buildPath); if (!File.Exists(previousBundlePath)) { //Logging this as a warning because users may choose to delete their bundles on disk which will trigger this state. Addressables.LogWarning($"CachedAssetState found for {entry.AssetPath} but the previous bundle at {previousBundlePath} cannot be found. " + $"The modified assets will not be able to use the previously built bundle which will result in new bundles being created " + $"for these static content groups. This will point the Content Catalog to local bundles that do not exist on currently " + $"deployed versions of an application."); continue; } string builtBundlePath = contentUpdateContext.BundleToInternalBundleIdMap[fullInternalBundleName].Replace(loadPath, buildPath); AssetEntryRevertOperation operation = new AssetEntryRevertOperation() { BundleCatalogEntry = catalogBundleEntry, AssetEntry = entry, CurrentBuildPath = builtBundlePath, PreviousAssetState = previousAssetState, PreviousBuildPath = previousBundlePath }; operations.Add(operation); } return(operations); }
TResult DoBuild <TResult>(AddressablesDataBuilderInput builderInput, AddressableAssetSettings aaSettings, AddressableAssetsBuildContext aaContext) where TResult : IDataBuilderResult { if (m_AllBundleInputDefinitions.Count > 0) { if (!BuildUtility.CheckModifiedScenesAndAskToSave()) { return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "Unsaved scenes")); } var buildTarget = builderInput.Target; var buildTargetGroup = builderInput.TargetGroup; var buildParams = new AddressableAssetsBundleBuildParameters(aaSettings, aaContext.bundleToAssetGroup, buildTarget, buildTargetGroup, aaSettings.buildSettings.bundleBuildPath); var builtinShaderBundleName = aaSettings.DefaultGroup.Name.ToLower().Replace(" ", "").Replace('\\', '/').Replace("//", "/") + "_unitybuiltinshaders.bundle"; var buildTasks = RuntimeDataBuildTasks(aaSettings.buildSettings.compileScriptsInVirtualMode, builtinShaderBundleName); ExtractDataTask extractData = new ExtractDataTask(); buildTasks.Add(extractData); string aaPath = aaSettings.AssetPath; IBundleBuildResults results; var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(m_AllBundleInputDefinitions), out results, buildTasks, aaContext); if (exitCode < ReturnCode.Success) { return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "SBP Error" + exitCode)); } if (aaSettings == null && !string.IsNullOrEmpty(aaPath)) { aaSettings = AssetDatabase.LoadAssetAtPath <AddressableAssetSettings>(aaPath); } } var bundledAssets = new Dictionary <object, HashSet <string> >(); foreach (var loc in aaContext.locations) { if (loc.Dependencies != null && loc.Dependencies.Count > 0) { for (int i = 0; i < loc.Dependencies.Count; i++) { var dep = loc.Dependencies[i]; HashSet <string> assetsInBundle; if (!bundledAssets.TryGetValue(dep, out assetsInBundle)) { bundledAssets.Add(dep, assetsInBundle = new HashSet <string>()); } if (i == 0 && !assetsInBundle.Contains(loc.InternalId)) //only add the asset to the first bundle... { assetsInBundle.Add(loc.InternalId); } } } } foreach (var bd in bundledAssets) { AddressableAssetGroup group = aaSettings.DefaultGroup; string groupGuid; if (aaContext.bundleToAssetGroup.TryGetValue(bd.Key as string, out groupGuid)) { group = aaSettings.FindGroup(g => g.Guid == groupGuid); } var schema = group.GetSchema <BundledAssetGroupSchema>(); if (schema != null) { var bundleLocData = aaContext.locations.First(s => s.Keys[0] == bd.Key); var isLocalBundle = IsInternalIdLocal(bundleLocData.InternalId); uint crc = (uint)UnityEngine.Random.Range(0, int.MaxValue); var hash = Guid.NewGuid().ToString(); string originalBundleName = bd.Key as string; string newBundleName = BuildUtility.GetNameWithHashNaming(schema.BundleNaming, hash, originalBundleName); bundleLocData.InternalId = bundleLocData.InternalId.Remove(bundleLocData.InternalId.Length - originalBundleName.Length) + newBundleName; var abb = m_AllBundleInputDefinitions.FirstOrDefault(a => a.assetBundleName == originalBundleName); var virtualBundleName = AddressablesRuntimeProperties.EvaluateString(bundleLocData.InternalId); var bundleData = new VirtualAssetBundle(virtualBundleName, isLocalBundle, crc, hash); long dataSize = 0; long headerSize = 0; foreach (var a in bd.Value) { var i = Array.IndexOf(abb.addressableNames, a); var assetPath = abb.assetNames[i]; var size = ComputeSize(assetPath); var vab = new VirtualAssetBundleEntry(a, size); vab.m_AssetPath = assetPath; bundleData.Assets.Add(vab); dataSize += size; headerSize += a.Length * 5; //assume 5x path length overhead size per item, probably much less } if (bd.Value.Count == 0) { dataSize = 100 * 1024; headerSize = 1024; } bundleData.SetSize(dataSize, headerSize); var requestOptions = new VirtualAssetBundleRequestOptions { Crc = schema.UseAssetBundleCrc ? crc : 0, Hash = schema.UseAssetBundleCache ? hash : "", ChunkedTransfer = schema.ChunkedTransfer, RedirectLimit = schema.RedirectLimit, RetryCount = schema.RetryCount, Timeout = schema.Timeout, BundleName = Path.GetFileName(bundleLocData.InternalId), BundleSize = dataSize + headerSize }; bundleLocData.Data = requestOptions; var bundleProviderId = schema.GetBundleCachedProviderId(); var virtualBundleRuntimeData = m_CreatedProviderIds[bundleProviderId]; virtualBundleRuntimeData.AssetBundles.Add(bundleData); } } foreach (var kvp in m_CreatedProviderIds) { if (kvp.Value != null) { var bundleProviderData = ObjectInitializationData.CreateSerializedInitializationData <VirtualAssetBundleProvider>(kvp.Key, kvp.Value); m_ResourceProviderData.Add(bundleProviderData); } } var contentCatalog = new ContentCatalogData(ResourceManagerRuntimeData.kCatalogAddress); contentCatalog.SetData(aaContext.locations.OrderBy(f => f.InternalId).ToList(), aaContext.Settings.OptimizeCatalogSize); contentCatalog.ResourceProviderData.AddRange(m_ResourceProviderData); foreach (var t in aaContext.providerTypes) { contentCatalog.ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData(t)); } contentCatalog.InstanceProviderData = ObjectInitializationData.CreateSerializedInitializationData(instanceProviderType.Value); contentCatalog.SceneProviderData = ObjectInitializationData.CreateSerializedInitializationData(sceneProviderType.Value); //save catalog WriteFile(string.Format(m_PathFormat, "", "catalog"), JsonUtility.ToJson(contentCatalog), builderInput.Registry); foreach (var io in aaSettings.InitializationObjects) { if (io is IObjectInitializationDataProvider) { aaContext.runtimeData.InitializationObjects.Add((io as IObjectInitializationDataProvider).CreateObjectInitializationData()); } } var settingsPath = string.Format(m_PathFormat, "", "settings"); WriteFile(settingsPath, JsonUtility.ToJson(aaContext.runtimeData), builderInput.Registry); //inform runtime of the init data path var runtimeSettingsPath = string.Format(m_PathFormat, "file://{UnityEngine.Application.dataPath}/../", "settings"); PlayerPrefs.SetString(Addressables.kAddressablesRuntimeDataPath, runtimeSettingsPath); var result = AddressableAssetBuildResult.CreateResult <TResult>(settingsPath, aaContext.locations.Count); return(result); }
public override void PostProcessBundles(AddressableAssetGroup assetGroup, List <string> buildBundles, List <string> outputBundles, IBundleBuildResults buildResult, ResourceManagerRuntimeData runtimeData, List <ContentCatalogDataEntry> locations, FileRegistry registry, Dictionary <string, ContentCatalogDataEntry> primaryKeyToCatalogEntry, Dictionary <string, string> bundleRenameMap, List <Action> postCatalogUpdateCallbacks) { var schema = assetGroup.GetSchema <BundledAssetGroupSchema>(); if (schema == null) { return; } var path = schema.BuildPath.GetValue(assetGroup.Settings); if (string.IsNullOrEmpty(path)) { return; } for (int i = 0; i < buildBundles.Count; ++i) { if (primaryKeyToCatalogEntry.TryGetValue(buildBundles[i], out ContentCatalogDataEntry dataEntry)) { var info = buildResult.BundleInfos[buildBundles[i]]; var requestOptions = new AssetBundleEncryptRequestOptions { Crc = schema.UseAssetBundleCrc ? info.Crc : 0, UseCrcForCachedBundle = schema.UseAssetBundleCrcForCachedBundles, Hash = schema.UseAssetBundleCache ? info.Hash.ToString() : "", ChunkedTransfer = schema.ChunkedTransfer, RedirectLimit = schema.RedirectLimit, RetryCount = schema.RetryCount, Timeout = schema.Timeout, BundleName = Path.GetFileName(info.FileName), BundleSize = GetFileSize(info.FileName) }; dataEntry.Data = requestOptions; int extensionLength = Path.GetExtension(outputBundles[i]).Length; string[] deconstructedBundleName = outputBundles[i].Substring(0, outputBundles[i].Length - extensionLength).Split('_'); string reconstructedBundleName = string.Join("_", deconstructedBundleName, 1, deconstructedBundleName.Length - 1) + ".bundle"; outputBundles[i] = ConstructAssetBundleName(assetGroup, schema, info, reconstructedBundleName); dataEntry.InternalId = dataEntry.InternalId.Remove(dataEntry.InternalId.Length - buildBundles[i].Length) + outputBundles[i]; dataEntry.Keys[0] = outputBundles[i]; ReplaceDependencyKeys(buildBundles[i], outputBundles[i], locations); Debug.Log(outputBundles[i] + "crc = " + requestOptions.Crc + " hash = " + requestOptions.Hash); if (!m_BundleToInternalId.ContainsKey(buildBundles[i])) { m_BundleToInternalId.Add(buildBundles[i], dataEntry.InternalId); } if (dataEntry.InternalId.StartsWith("http:\\")) { dataEntry.InternalId = dataEntry.InternalId.Replace("http:\\", "http://").Replace("\\", "/"); } if (dataEntry.InternalId.StartsWith("https:\\")) { dataEntry.InternalId = dataEntry.InternalId.Replace("https:\\", "https://").Replace("\\", "/"); } dataEntry.InternalId = CheckNameNeedStripped(assetGroup, dataEntry.InternalId); } else { Debug.LogWarningFormat("Unable to find ContentCatalogDataEntry for bundle {0}.", outputBundles[i]); } //获取bundle的保存路径 var targetPath = Path.Combine(path, outputBundles[i]); //判断目录是否存在 if (!Directory.Exists(Path.GetDirectoryName(targetPath))) { Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); } File.Copy(Path.Combine(assetGroup.Settings.buildSettings.bundleBuildPath, buildBundles[i]), targetPath, true); var nameWithourHash = CheckNameNeedStripped(assetGroup, outputBundles[i]); EncodeAssetBundleBySetOffset(nameWithourHash, targetPath); var bundleName = Path.GetFileName(nameWithourHash); if (IsBuildInAssetBundle(bundleName)) { string RuntimePath = UnityEngine.AddressableAssets.Addressables.RuntimePath; string destPath = Path.Combine(System.Environment.CurrentDirectory, RuntimePath, PlatformMappingService.GetPlatform().ToString(), nameWithourHash); if (!Directory.Exists(Path.GetDirectoryName(destPath))) { Directory.CreateDirectory(Path.GetDirectoryName(destPath)); } if (!File.Exists(destPath)) { File.Copy(targetPath, destPath); } } AddPostCatalogUpdatesInternal(assetGroup, postCatalogUpdateCallbacks, dataEntry, targetPath); registry.AddFile(targetPath); } }
private void PostProcessCatalogEnteries(AddressableAssetGroup group, IBundleWriteData writeData, List <ContentCatalogDataEntry> locations, FileRegistry fileRegistry) { if (!group.HasSchema <BundledAssetGroupSchema>() || !File.Exists(ContentUpdateScript.GetContentStateDataPath(false))) { return; } AddressablesContentState contentState = ContentUpdateScript.LoadContentState(ContentUpdateScript.GetContentStateDataPath(false)); foreach (AddressableAssetEntry entry in group.entries) { CachedAssetState cachedAsset = contentState.cachedInfos.FirstOrDefault(i => i.asset.guid.ToString() == entry.guid); if (cachedAsset != null) { GUID guid = new GUID(entry.guid); if (!writeData.AssetToFiles.ContainsKey(guid)) { continue; } string file = writeData.AssetToFiles[guid][0]; string fullBundleName = writeData.FileToBundle[file]; string convertedLocation = m_BundleToInternalId[fullBundleName]; ContentCatalogDataEntry catalogBundleEntry = locations.FirstOrDefault((loc) => loc.InternalId == (convertedLocation)); if (catalogBundleEntry != null) { if (entry.parentGroup.Guid == cachedAsset.groupGuid) { //Asset hash hasn't changed if (AssetDatabase.GetAssetDependencyHash(entry.AssetPath) == cachedAsset.asset.hash) { if (catalogBundleEntry.InternalId != cachedAsset.bundleFileId) { string builtBundlePath = m_BundleToInternalId[fullBundleName].Replace( group.GetSchema <BundledAssetGroupSchema>().LoadPath.GetValue(group.Settings), group.GetSchema <BundledAssetGroupSchema>().BuildPath.GetValue(group.Settings)); string cachedBundlePath = cachedAsset.bundleFileId?.Replace( group.GetSchema <BundledAssetGroupSchema>().LoadPath.GetValue(group.Settings), group.GetSchema <BundledAssetGroupSchema>().BuildPath.GetValue(group.Settings)); //Need to check and make sure our cached version exists if (!string.IsNullOrEmpty(cachedBundlePath) && File.Exists(cachedBundlePath)) { //Try and replace the new bundle entry with the cached one and delete the new bundle if (File.Exists(builtBundlePath) && fileRegistry.ReplaceBundleEntry( Path.GetFileNameWithoutExtension(convertedLocation), cachedAsset.bundleFileId)) { File.Delete(builtBundlePath); catalogBundleEntry.InternalId = cachedAsset.bundleFileId; catalogBundleEntry.Data = cachedAsset.data; entry.BundleFileId = cachedAsset.bundleFileId; } } } } entry.BundleFileId = catalogBundleEntry.InternalId; cachedAsset.bundleFileId = catalogBundleEntry.InternalId; } } } } }
public void Complete() { try { LogText(""); LogText("****************************************************"); LogText("Generating from recipes: " + DateTime.Now.ToString()); LogText("****************************************************"); LogText(""); bool IncludeRecipes = UMAEditorUtilities.GetConfigValue(UMAEditorUtilities.ConfigToggle_IncludeRecipes, false); bool IncludeOthers = UMAEditorUtilities.GetConfigValue(UMAEditorUtilities.ConfigToggle_IncludeOther, false); string DefaultAddressableLabel = UMAEditorUtilities.GetDefaultAddressableLabel(); RecipeExtraLabels = new Dictionary <string, List <string> >(); if (UMAEditorUtilities.GetConfigValue(UMAEditorUtilities.ConfigToggle_AddCollectionLabels, false)) { var WardrobeCollections = UMAAssetIndexer.Instance.GetAllAssets <UMAWardrobeCollection>(); foreach (var wc in WardrobeCollections) { if (wc == null) { continue; } string label = wc.AssignedLabel; List <string> recipes = wc.wardrobeCollection.GetAllRecipeNamesInCollection(); foreach (string recipe in recipes) { if (RecipeExtraLabels.ContainsKey(recipe) == false) { RecipeExtraLabels.Add(recipe, new List <string>()); } RecipeExtraLabels[recipe].Add(label); } } } float pos = 0.0f; float inc = 1.0f / Recipes.Count; foreach (UMAPackedRecipeBase uwr in Recipes) { List <string> ExtraLabels = new List <string>(); if (RecipeExtraLabels.ContainsKey(uwr.name)) { ExtraLabels = RecipeExtraLabels[uwr.name]; } LogText(""); LogText("Processing recipe: " + uwr.name + " Label: " + uwr.AssignedLabel); EditorUtility.DisplayProgressBar("Generating", "processing recipe: " + uwr.name, pos); List <AssetItem> items = Index.GetAssetItems(uwr, true); foreach (AssetItem ai in items) { if (AddressableItems.ContainsKey(ai) == false) { AddressableItems.Add(ai, new List <string>()); AddressableItems[ai].Add(DefaultAddressableLabel); } AddressableItems[ai].Add(uwr.AssignedLabel); AddressableItems[ai].AddRange(ExtraLabels); } if (IncludeRecipes) { AssetItem RecipeItem = UMAAssetIndexer.Instance.GetRecipeItem(uwr); if (AddressableItems.ContainsKey(RecipeItem) == false) { AddressableItems.Add(RecipeItem, new List <string>()); AddressableItems[RecipeItem].Add(DefaultAddressableLabel); } AddressableItems[RecipeItem].Add(uwr.AssignedLabel); AddressableItems[RecipeItem].Add("UMA_Recipes"); AddressableItems[RecipeItem].AddRange(ExtraLabels); } pos += inc; } if (IncludeOthers) { AddAssetItems(typeof(RaceData), DefaultAddressableLabel); AddAssetItems(typeof(RuntimeAnimatorController), DefaultAddressableLabel); AddAssetItems(typeof(TextAsset), DefaultAddressableLabel); AddAssetItems(typeof(DynamicUMADnaAsset), DefaultAddressableLabel); } // Create the shared group that has each item packed separately. AddressableAssetGroup sharedGroup = AddressableUtility.AddressableSettings.FindGroup(SharedGroupName); if (sharedGroup == null) { sharedGroup = AddressableUtility.AddressableSettings.CreateGroup(SharedGroupName, false, false, true, AddressableUtility.AddressableSettings.DefaultGroup.Schemas); sharedGroup.GetSchema <BundledAssetGroupSchema>().BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately; } pos = 0.0f; inc = 1.0f / AddressableItems.Count; StringBuilder sb = new StringBuilder(); foreach (AssetItem ai in AddressableItems.Keys) { ai.IsAddressable = true; ai.AddressableAddress = ""; // let the system assign it if we are generating. ai.AddressableGroup = sharedGroup.name; EditorUtility.DisplayProgressBar("Generating", "Processing Asset: " + ai.Item.name, pos); sb.Clear(); foreach (string s in AddressableItems[ai]) { sb.Append(s); sb.Append(';'); } ai.AddressableLabels = sb.ToString(); bool found = AssetDatabase.TryGetGUIDAndLocalFileIdentifier(ai.Item.GetInstanceID(), out string itemGUID, out long localID); UMAAddressablesSupport.Instance.AddItemToSharedGroup(itemGUID, ai.AddressableAddress, AddressableItems[ai], sharedGroup); if (ai._Type == typeof(OverlayDataAsset)) { OverlayDataAsset od = ai.Item as OverlayDataAsset; if (od == null) { Debug.Log("Invalid overlay in recipe: " + ai._Name + ". Skipping."); continue; } #if INCL_TEXTURE2D foreach (Texture tex in od.textureList) { if (tex == null) { continue; } if (tex as Texture2D == null) { Debug.Log("Texture is not Texture2D!!! " + tex.name); continue; } string path = AssetDatabase.GetAssetPath(tex.GetInstanceID()); string Address = "Texture2D-" + tex.name + "-" + path.GetHashCode(); found = AssetDatabase.TryGetGUIDAndLocalFileIdentifier(tex.GetInstanceID(), out string texGUID, out long texlocalID); if (found) { UMAAddressablesSupport.Instance.AddItemToSharedGroup(texGUID, AssetItem.AddressableFolder + Address, AddressableItems[ai], sharedGroup); } } #endif } pos += inc; } UMAAddressablesSupport.Instance.AssignAddressableInformation(); Type[] types = Index.GetTypes(); foreach (Type t in types) { UMAAddressablesSupport.Instance.ReleaseReferences(t); } UMAAddressablesSupport.Instance.CleanupAddressables(true); } finally { EditorUtility.ClearProgressBar(); UMAAssetIndexer.Instance.ForceSave(); } }
private void CreateAddressableSettings(bool localMode) { AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.GetSettings(true); settings.ActivePlayModeDataBuilderIndex = localMode ? 0 : 2; settings.BuildRemoteCatalog = true; settings.DisableCatalogUpdateOnStartup = true; // don't include built-in data, causes shader issues settings.groups.ForEach(g => { PlayerDataGroupSchema schema = g.GetSchema <PlayerDataGroupSchema>(); if (schema != null) { schema.IncludeBuildSettingsScenes = false; schema.IncludeResourcesFolders = false; } }); // setup profiles AddressableAssetProfileSettings profile = settings.profileSettings; // activate and (re)group assets foreach (string dir in GetLevelPaths()) { string levelName = Path.GetFileName(dir); bool isBase = levelName == "Base"; // create one profile per level string profileId = profile.GetProfileId(levelName); if (string.IsNullOrEmpty(profileId)) { profileId = profile.AddProfile(levelName, settings.activeProfileId); } string guid = AssetDatabase.AssetPathToGUID($"Assets/Levels/{levelName}"); // create group if non-existent AddressableAssetGroup group = settings.groups.Where(g => g.name == levelName).FirstOrDefault(); if (group == null) { group = CreateAssetGroup <BundledAssetGroupSchema>(settings, levelName); } // set correct path AddressableAssetEntry entry = settings.CreateOrMoveEntry(guid, group); entry.SetAddress($"Levels/{levelName}"); // set variables string localRoot = Application.dataPath + $"/../Library/com.unity.addressables/aa/Windows/Levels/{levelName}/[BuildTarget]"; profile.SetValue(profileId, AddressableAssetSettings.kLocalBuildPath, localRoot); profile.SetValue(profileId, AddressableAssetSettings.kLocalLoadPath, localRoot); profile.SetValue(profileId, AddressableAssetSettings.kRemoteBuildPath, $"ServerData/Levels/{levelName}/[BuildTarget]"); profile.SetValue(profileId, AddressableAssetSettings.kRemoteLoadPath, $"{AWSUtil.S3Root}Levels/{levelName}/[BuildTarget]"); // ensure correct group settings BundledAssetGroupSchema groupSchema = group.GetSchema <BundledAssetGroupSchema>(); groupSchema.UseAssetBundleCache = true; groupSchema.UseAssetBundleCrc = false; groupSchema.IncludeInBuild = isBase ? true : false; groupSchema.BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.NoHash; // hash to disimbiguate identically named files yields same error messages, e.g. standard shaders groupSchema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether; groupSchema.Compression = BundledAssetGroupSchema.BundleCompressionMode.LZ4; groupSchema.BuildPath.SetVariableByName(settings, localMode ? AddressableAssetSettings.kLocalBuildPath : AddressableAssetSettings.kRemoteBuildPath); groupSchema.LoadPath.SetVariableByName(settings, localMode ? AddressableAssetSettings.kLocalLoadPath : AddressableAssetSettings.kRemoteLoadPath); } }